home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / amyboard / xboard-3.3.pl0 / xboard.c < prev    next >
C/C++ Source or Header  |  1995-08-12  |  119KB  |  4,159 lines

  1. /*
  2.  * xboard.c -- X front end for XBoard
  3.  * $Id: xboard.c,v 1.48 1995/07/28 05:23:42 mann Exp $
  4.  *
  5.  * Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts.
  6.  * Enhancements Copyright 1992-95 Free Software Foundation, Inc.
  7.  *
  8.  * The following terms apply to Digital Equipment Corporation's copyright
  9.  * interest in XBoard:
  10.  * ------------------------------------------------------------------------
  11.  * All Rights Reserved
  12.  *
  13.  * Permission to use, copy, modify, and distribute this software and its
  14.  * documentation for any purpose and without fee is hereby granted,
  15.  * provided that the above copyright notice appear in all copies and that
  16.  * both that copyright notice and this permission notice appear in
  17.  * supporting documentation, and that the name of Digital not be
  18.  * used in advertising or publicity pertaining to distribution of the
  19.  * software without specific, written prior permission.
  20.  *
  21.  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  22.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  23.  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  24.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  25.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  26.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  27.  * SOFTWARE.
  28.  * ------------------------------------------------------------------------
  29.  *
  30.  * The following terms apply to the enhanced version of XBoard distributed
  31.  * by the Free Software Foundation:
  32.  * ------------------------------------------------------------------------
  33.  * This program is free software; you can redistribute it and/or modify
  34.  * it under the terms of the GNU General Public License as published by
  35.  * the Free Software Foundation; either version 2 of the License, or
  36.  * (at your option) any later version.
  37.  *
  38.  * This program is distributed in the hope that it will be useful,
  39.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  40.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  41.  * GNU General Public License for more details.
  42.  *
  43.  * You should have received a copy of the GNU General Public License
  44.  * along with this program; if not, write to the Free Software
  45.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  46.  * ------------------------------------------------------------------------
  47.  *
  48.  * See the file ChangeLog for a revision history.
  49.  */
  50.  
  51. #include <config.h>
  52.  
  53. #include <stdio.h>
  54. #include <ctype.h>
  55. #include <signal.h>
  56. #include <errno.h>
  57. #include <sys/types.h>
  58. #include <sys/stat.h>
  59. #include <pwd.h>
  60.  
  61. #if !OMIT_SOCKETS
  62. # if HAVE_SYS_SOCKET_H
  63. #  include <sys/socket.h>
  64. #  include <netinet/in.h>
  65. #  include <netdb.h>
  66. # else /* not HAVE_SYS_SOCKET_H */
  67. #  if HAVE_LAN_SOCKET_H
  68. #   include <lan/socket.h>
  69. #   include <lan/in.h>
  70. #   include <lan/netdb.h>
  71. #  else /* not HAVE_LAN_SOCKET_H */
  72. #   define OMIT_SOCKETS 1
  73. #  endif /* not HAVE_LAN_SOCKET_H */
  74. # endif /* not HAVE_SYS_SOCKET_H */
  75. #endif /* !OMIT_SOCKETS */
  76.  
  77. #if STDC_HEADERS
  78. # include <stdlib.h>
  79. # include <string.h>
  80. #else /* not STDC_HEADERS */
  81. extern char *getenv();
  82. # if HAVE_STRING_H
  83. #  include <string.h>
  84. # else /* not HAVE_STRING_H */
  85. #  include <strings.h>
  86. # endif /* not HAVE_STRING_H */
  87. #endif /* not STDC_HEADERS */
  88.  
  89. #if HAVE_SYS_FCNTL_H
  90. # include <sys/fcntl.h>
  91. #else /* not HAVE_SYS_FCNTL_H */
  92. # if HAVE_FCNTL_H
  93. #  include <fcntl.h>
  94. # endif /* HAVE_FCNTL_H */
  95. #endif /* not HAVE_SYS_FCNTL_H */
  96.  
  97. #if HAVE_SYS_SYSTEMINFO_H
  98. # include <sys/systeminfo.h>
  99. #endif /* HAVE_SYS_SYSTEMINFO_H */
  100.  
  101. #if HAVE_UNISTD_H
  102. # include <unistd.h>
  103. #endif
  104.  
  105. #if HAVE_SYS_WAIT_H
  106. # include <sys/wait.h>
  107. #endif
  108.  
  109. #include <X11/Intrinsic.h>
  110. #include <X11/StringDefs.h>
  111. #include <X11/Shell.h>
  112. #include <X11/Xaw/Dialog.h>
  113. #include <X11/Xaw/Form.h>
  114. #include <X11/Xaw/List.h>
  115. #include <X11/Xaw/Label.h>
  116. #include <X11/Xaw/SimpleMenu.h>
  117. #include <X11/Xaw/SmeBSB.h>
  118. #include <X11/Xaw/SmeLine.h>
  119. #include <X11/Xaw/Box.h>
  120. #include <X11/Xaw/MenuButton.h>
  121. #include <X11/cursorfont.h>
  122. #include <X11/Xaw/Text.h>
  123. #include <X11/Xaw/AsciiText.h>
  124.  
  125. #include "common.h"
  126. #include "frontend.h"
  127. #include "backend.h"
  128. #include "moves.h"
  129. #include "xboard.h"
  130. #include "childio.h"
  131. #include "bitmaps.h"
  132. #include "xgamelist.h"
  133. #include "xedittags.h"
  134.  
  135. typedef struct {
  136.     String string;
  137.     XtActionProc proc;
  138. } MenuItem;
  139.  
  140. typedef struct {
  141.     String name;
  142.     MenuItem *mi;
  143. } Menu;
  144.  
  145. void main P((int argc, char **argv));
  146. RETSIGTYPE CmailSigHandler P((int sig));
  147. RETSIGTYPE IntSigHandler P((int sig));
  148. void CreateGCs P((void));
  149. void CreatePieces P((void));
  150. void CreatePieceMenus P((void));
  151. Widget CreateMenuBar P((Menu *mb));
  152. Widget CreateButtonBar P ((MenuItem *mi));
  153. char *FindFont P((char *pattern, int targetPxlSize));
  154. void PieceMenuPopup P((Widget w, XEvent *event,
  155.                String *params, Cardinal *num_params));
  156. static void PieceMenuSelect P((Widget w, ChessSquare piece, caddr_t junk));
  157. void ReadBitmap P((Pixmap *pm, String name, unsigned char bits[],
  158.            u_int wreq, u_int hreq));
  159. void CreateGrid P((void));
  160. int EventToSquare P((int x));
  161. void DrawSquare P((int row, int column, ChessSquare piece));
  162. void EventProc P((Widget widget, caddr_t unused, XEvent *event));
  163. void HandleUserMove P((Widget w, XEvent *event,
  164.              String *prms, Cardinal *nprms));
  165. void WhiteClock P((Widget w, XEvent *event,
  166.            String *prms, Cardinal *nprms));
  167. void BlackClock P((Widget w, XEvent *event,
  168.            String *prms, Cardinal *nprms));
  169. void DrawPositionProc P((Widget w, XEvent *event,
  170.              String *prms, Cardinal *nprms));
  171. void XDrawPosition P((Widget w, /*Boolean*/int repaint, 
  172.              Board board));
  173. void CommentPopUp P((char *title, char *label));
  174. void CommentPopDown P((void));
  175. void CommentCallback P((Widget w, XtPointer client_data,
  176.             XtPointer call_data));
  177. void FileNamePopUp P((char *label, char *def,
  178.               FileProc proc, char *openMode));
  179. void FileNameCallback P((Widget w, XtPointer client_data,
  180.              XtPointer call_data));
  181. void FileNameAction P((Widget w, XEvent *event,
  182.                String *prms, Cardinal *nprms));
  183. void PromotionPopUp P((void));
  184. void PromotionCallback P((Widget w, XtPointer client_data,
  185.               XtPointer call_data));
  186. void EditCommentPopDown P((void));
  187. void EditCommentCallback P((Widget w, XtPointer client_data,
  188.                 XtPointer call_data));
  189. void SelectCommand P((Widget w, XtPointer client_data, XtPointer call_data));
  190. void ResetProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  191. void LoadGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  192. void LoadNextGameProc P((Widget w, XEvent *event, String *prms,
  193.              Cardinal *nprms));
  194. void LoadPrevGameProc P((Widget w, XEvent *event, String *prms,
  195.              Cardinal *nprms));
  196. void ReloadGameProc P((Widget w, XEvent *event, String *prms,
  197.                Cardinal *nprms));
  198. void LoadPositionProc P((Widget w, XEvent *event,
  199.              String *prms, Cardinal *nprms));
  200. void SaveGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  201. void SavePositionProc P((Widget w, XEvent *event,
  202.              String *prms, Cardinal *nprms));
  203. void MailMoveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  204. void ReloadCmailMsgProc P((Widget w, XEvent *event, String *prms,
  205.                 Cardinal *nprms));
  206. void QuitProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  207. void PauseProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  208. void MachineBlackProc P((Widget w, XEvent *event, String *prms,
  209.              Cardinal *nprms));
  210. void MachineWhiteProc P((Widget w, XEvent *event,
  211.              String *prms, Cardinal *nprms));
  212. void TwoMachinesProc P((Widget w, XEvent *event, String *prms,
  213.             Cardinal *nprms));
  214. void IcsClientProc P((Widget w, XEvent *event, String *prms,
  215.               Cardinal *nprms));
  216. void EditGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  217. void EditPositionProc P((Widget w, XEvent *event,
  218.              String *prms, Cardinal *nprms));
  219. void EditCommentProc P((Widget w, XEvent *event,
  220.             String *prms, Cardinal *nprms));
  221. void AcceptProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  222. void DeclineProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  223. void CallFlagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  224. void DrawProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  225. void AbortProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  226. void AdjournProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  227. void ResignProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  228. void StopObservingProc P((Widget w, XEvent *event, String *prms,
  229.               Cardinal *nprms));
  230. void StopExaminingProc P((Widget w, XEvent *event, String *prms,
  231.               Cardinal *nprms));
  232. void BackwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  233. void ForwardProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  234. void ToStartProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  235. void ToEndProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  236. void RevertProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  237. void TruncateGameProc P((Widget w, XEvent *event, String *prms,
  238.              Cardinal *nprms));
  239. void RetractMoveProc P((Widget w, XEvent *event, String *prms,
  240.             Cardinal *nprms));
  241. void MoveNowProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  242. void AlwaysQueenProc P((Widget w, XEvent *event, String *prms,
  243.             Cardinal *nprms));
  244. void AutocommProc P((Widget w, XEvent *event, String *prms,
  245.              Cardinal *nprms));
  246. void AutoflagProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  247. void AutobsProc P((Widget w, XEvent *event, String *prms,
  248.             Cardinal *nprms));
  249. void AutosaveProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  250. void BellProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  251. void FlipViewProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  252. void OldSaveStyleProc P((Widget w, XEvent *event, String *prms,
  253.              Cardinal *nprms));
  254. void QuietPlayProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  255. void ShowCoordsProc P((Widget w, XEvent *event, String *prms,
  256.                Cardinal *nprms));
  257. void ShowThinkingProc P((Widget w, XEvent *event, String *prms,
  258.              Cardinal *nprms));
  259. void HintProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  260. void BookProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  261. void AboutGameProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  262. void AboutProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  263. void NothingProc P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  264. void Iconify P((Widget w, XEvent *event, String *prms, Cardinal *nprms));
  265. void DisplayMove P((int moveNumber));
  266. void DisplayTitle P((char *title));
  267. void Usage P((void));
  268. void ICSInitScript P((void));
  269. int LoadGamePopUp P((FILE *f, int gameNumber, char *title));
  270. void ErrorPopDown P((void));
  271.  
  272. /*
  273. * XBoard depends on Xt R4 or higher
  274. */
  275. int xtVersion = XtSpecificationRelease;
  276.  
  277. int xScreen;
  278. Display *xDisplay;
  279. Window xBoardWindow;
  280. Pixel lightSquareColor, darkSquareColor, whitePieceColor, blackPieceColor;
  281. GC lightSquareGC, darkSquareGC, lineGC, wdPieceGC, wlPieceGC,
  282.   bdPieceGC, blPieceGC, wbPieceGC, bwPieceGC, coordGC;
  283. Pixmap solidPawnBitmap, solidRookBitmap, solidKnightBitmap,
  284.   solidBishopBitmap, solidQueenBitmap, solidKingBitmap,
  285.   outlinePawnBitmap, outlineRookBitmap, outlineKnightBitmap,
  286.   outlineBishopBitmap, outlineQueenBitmap, outlineKingBitmap,
  287.   iconPixmap, wIconPixmap, bIconPixmap, xMarkPixmap;
  288. Widget shellWidget, formWidget, boardWidget, messageWidget, titleWidget,
  289.   whiteTimerWidget, blackTimerWidget, titleWidget, widgetList[16], 
  290.   commentShell, promotionShell, whitePieceMenu, blackPieceMenu,
  291.   menuBarWidget, buttonBarWidget, editShell, errorShell;
  292. XSegment gridSegments[(BOARD_SIZE + 1) * 2];
  293. Font clockFontID, coordFontID;
  294. XFontStruct *clockFontStruct, *coordFontStruct;
  295. XtAppContext appContext;
  296.  
  297. FileProc fileProc;
  298. char *fileOpenMode;
  299.  
  300. Position commentX = -1, commentY = -1;
  301. Dimension commentW, commentH;
  302. static BoardSize boardSize = Large;
  303.  
  304. int squareSize = LARGE_SQUARE_SIZE, fromX = -1,
  305.   fromY = -1, toX, toY, commentUp = False, filenameUp = False,
  306.   promotionUp = False, pmFromX = -1, pmFromY = -1, editUp = False,
  307.   errorUp = False, errorExitStatus = -1, lineGap;
  308. Pixel timerForegroundPixel, timerBackgroundPixel;
  309. Pixel buttonForegroundPixel, buttonBackgroundPixel;
  310. char *chessDir, *programName;
  311.  
  312. MenuItem fileMenu[] = {
  313.     {"Reset Game", ResetProc},
  314.     {"----", NothingProc},
  315.     {"Load Game", LoadGameProc},
  316.     {"Load Next Game", LoadNextGameProc},
  317.     {"Load Previous Game", LoadPrevGameProc},
  318.     {"Reload Same Game", ReloadGameProc},
  319.     {"Load Position", LoadPositionProc},
  320.     {"----", NothingProc},
  321.     {"Save Game", SaveGameProc},
  322.     {"Save Position", SavePositionProc},
  323.     {"----", NothingProc},
  324.     {"Mail Move", MailMoveProc},
  325.     {"Reload CMail Message", ReloadCmailMsgProc},
  326.     {"----", NothingProc},
  327.     {"Exit", QuitProc},
  328.     {NULL, NULL}
  329. };
  330.  
  331. MenuItem modeMenu[] = {
  332.     {"Machine White", MachineWhiteProc},
  333.     {"Machine Black", MachineBlackProc},
  334.     {"Two Machines", TwoMachinesProc},
  335.     {"ICS Client", IcsClientProc},
  336.     {"Edit Game", EditGameProc},
  337.     {"Edit Position", EditPositionProc},
  338.     {"----", NothingProc},
  339.     {"Show Game List", ShowGameListProc},
  340.     {"Edit Tags", EditTagsProc},
  341.     {"Edit Comment", EditCommentProc},
  342.     {"Pause", PauseProc},
  343.     {NULL, NULL}
  344. };
  345.  
  346. MenuItem actionMenu[] = {
  347.     {"Accept", AcceptProc},
  348.     {"Decline", DeclineProc},
  349.     {"----", NothingProc},    
  350.     {"Call Flag", CallFlagProc},
  351.     {"Draw", DrawProc},
  352.     {"Adjourn", AdjournProc},
  353.     {"Abort", AbortProc},
  354.     {"Resign", ResignProc},
  355.     {"----", NothingProc},    
  356.     {"Stop Observing", StopObservingProc},
  357.     {"Stop Examining", StopExaminingProc},
  358.     {NULL, NULL}
  359. };
  360.  
  361. MenuItem stepMenu[] = {
  362.     {"Backward", BackwardProc},
  363.     {"Forward", ForwardProc},
  364.     {"Back to Start", ToStartProc},
  365.     {"Forward to End", ToEndProc},
  366.     {"Revert", RevertProc},
  367.     {"Truncate Game", TruncateGameProc},
  368.     {"----", NothingProc},    
  369.     {"Move Now", MoveNowProc},
  370.     {"Retract Move", RetractMoveProc},
  371.     {NULL, NULL}
  372. };    
  373.  
  374. MenuItem optionsMenu[] = {
  375.     {"Always Queen", AlwaysQueenProc},
  376.     {"Auto Comment", AutocommProc},
  377.     {"Auto Flag", AutoflagProc},
  378.     {"Auto Observe", AutobsProc},
  379.     {"Auto Save", AutosaveProc},
  380.     {"Bell", BellProc},
  381.     {"Flip View", FlipViewProc},
  382.     {"Old Save Style", OldSaveStyleProc},
  383.     {"Quiet Play", QuietPlayProc},
  384.     {"Show Coords", ShowCoordsProc},
  385.     {"Show Thinking", ShowThinkingProc},
  386.     {NULL, NULL}
  387. };
  388.  
  389. MenuItem helpMenu[] = {
  390.     {"Hint", HintProc},
  391.     {"Book", BookProc},
  392.     {"----", NothingProc},
  393.     {"About XBoard", AboutProc},
  394.     {NULL, NULL}
  395. };
  396.  
  397. Menu menuBar[] = {
  398.     {"File", fileMenu},
  399.     {"Mode", modeMenu},
  400.     {"Action", actionMenu},
  401.     {"Step", stepMenu},
  402.     {"Options", optionsMenu},
  403.     {"Help", helpMenu},
  404.     {NULL, NULL}
  405. };
  406.  
  407. #define PAUSE_BUTTON "P"
  408. MenuItem buttonBar[] = {
  409.     {"<<", ToStartProc},
  410.     {"<", BackwardProc},
  411.     {PAUSE_BUTTON, PauseProc},
  412.     {">", ForwardProc},
  413.     {">>", ToEndProc},
  414.     {NULL, NULL}
  415. };
  416.  
  417. #define PIECE_MENU_SIZE 10
  418. String pieceMenuStrings[PIECE_MENU_SIZE] = {
  419.     "----", "Pawn", "Knight", "Bishop", "Rook", "Queen", "King",
  420.     "----", "Empty square", "Clear board"
  421.   };
  422. /* must be in same order as PieceMenuStrings! */
  423. ChessSquare pieceMenuTranslation[2][PIECE_MENU_SIZE] = {
  424.     { (ChessSquare) 0, WhitePawn, WhiteKnight, WhiteBishop,
  425.     WhiteRook, WhiteQueen, WhiteKing,
  426.     (ChessSquare) 0, EmptySquare, ClearBoard },
  427.     { (ChessSquare) 0, BlackPawn, BlackKnight, BlackBishop,
  428.     BlackRook, BlackQueen, BlackKing,
  429.     (ChessSquare) 0, EmptySquare, ClearBoard },
  430. };
  431.  
  432. Arg shellArgs[] = {
  433.     { XtNwidth, 0 },
  434.     { XtNheight, 0 },
  435.     { XtNminWidth, 0 },
  436.     { XtNminHeight, 0 },
  437.     { XtNmaxWidth, 0 },
  438.     { XtNmaxHeight, 0 }
  439. };
  440.  
  441. Arg boardArgs[] = {
  442.     { XtNborderWidth, 0 },
  443.     { XtNwidth, 0 },
  444.     { XtNheight, 0 }
  445. };
  446.  
  447. Arg titleArgs[] = {
  448.     { XtNjustify, (XtArgVal) XtJustifyRight },
  449.     { XtNlabel, (XtArgVal) "starting..." },
  450.     { XtNresizable, (XtArgVal) True },
  451.     { XtNresize, (XtArgVal) False }
  452. };
  453.  
  454. Arg messageArgs[] = {
  455.     { XtNjustify, (XtArgVal) XtJustifyLeft },
  456.     { XtNlabel, (XtArgVal) "starting..." },
  457.     { XtNresizable, (XtArgVal) True },
  458.     { XtNresize, (XtArgVal) False }
  459. };
  460.  
  461. Arg timerArgs[] = {
  462.     { XtNborderWidth, 0 },
  463.     { XtNjustify, (XtArgVal) XtJustifyLeft }
  464. };
  465.  
  466. XtResource clientResources[] = {
  467.     { "whitePieceColor", "whitePieceColor", XtRString, sizeof(String),
  468.     XtOffset(AppDataPtr, whitePieceColor), XtRString,
  469.     WHITE_PIECE_COLOR },
  470.     { "blackPieceColor", "blackPieceColor", XtRString, sizeof(String),
  471.     XtOffset(AppDataPtr, blackPieceColor), XtRString,
  472.     BLACK_PIECE_COLOR },
  473.     { "lightSquareColor", "lightSquareColor", XtRString,
  474.     sizeof(String), XtOffset(AppDataPtr, lightSquareColor),
  475.     XtRString, LIGHT_SQUARE_COLOR }, 
  476.     { "darkSquareColor", "darkSquareColor", XtRString, sizeof(String),
  477.     XtOffset(AppDataPtr, darkSquareColor), XtRString,
  478.     DARK_SQUARE_COLOR },
  479.     { "movesPerSession", "movesPerSession", XtRInt, sizeof(int),
  480.     XtOffset(AppDataPtr, movesPerSession), XtRImmediate,
  481.     (XtPointer) MOVES_PER_SESSION },
  482.     { "initString", "initString", XtRString, sizeof(String),
  483.     XtOffset(AppDataPtr, initString), XtRString, INIT_STRING },
  484.     { "whiteString", "whiteString", XtRString, sizeof(String),
  485.     XtOffset(AppDataPtr, whiteString), XtRString, WHITE_STRING },
  486.     { "blackString", "blackString", XtRString, sizeof(String),
  487.     XtOffset(AppDataPtr, blackString), XtRString, BLACK_STRING },
  488.     { "firstChessProgram", "firstChessProgram", XtRString,
  489.     sizeof(String), XtOffset(AppDataPtr, firstChessProgram),
  490.     XtRString, FIRST_CHESS_PROGRAM },
  491.     { "secondChessProgram", "secondChessProgram", XtRString,
  492.     sizeof(String), XtOffset(AppDataPtr, secondChessProgram),
  493.     XtRString, SECOND_CHESS_PROGRAM },
  494.     { "noChessProgram", "noChessProgram", XtRBoolean,
  495.     sizeof(Boolean), XtOffset(AppDataPtr, noChessProgram),
  496.     XtRImmediate, (XtPointer) False },
  497.     { "firstHost", "firstHost", XtRString, sizeof(String),
  498.     XtOffset(AppDataPtr, firstHost), XtRString, FIRST_HOST },
  499.     { "secondHost", "secondHost", XtRString, sizeof(String),
  500.     XtOffset(AppDataPtr, secondHost), XtRString, SECOND_HOST },
  501.     { "bitmapDirectory", "bitmapDirectory", XtRString,
  502.     sizeof(String), XtOffset(AppDataPtr, bitmapDirectory),
  503.     XtRString, "" },
  504.     { "remoteShell", "remoteShell", XtRString, sizeof(String),
  505.     XtOffset(AppDataPtr, remoteShell), XtRString, REMOTE_SHELL },
  506.     { "remoteUser", "remoteUser", XtRString, sizeof(String),
  507.     XtOffset(AppDataPtr, remoteUser), XtRString, "" },
  508.     { "timeDelay", "timeDelay", XtRFloat, sizeof(float),
  509.     XtOffset(AppDataPtr, timeDelay), XtRString,
  510.     (XtPointer) TIME_DELAY_QUOTE },
  511.     { "timeControl", "timeControl", XtRString, sizeof(String),
  512.     XtOffset(AppDataPtr, timeControl), XtRString,
  513.     (XtPointer) TIME_CONTROL },
  514.     { "internetChessServerMode", "internetChessServerMode",
  515.     XtRBoolean, sizeof(Boolean),
  516.     XtOffset(AppDataPtr, icsActive), XtRImmediate,
  517.     (XtPointer) False },
  518.     { "internetChessServerHost", "internetChessServerHost",
  519.     XtRString, sizeof(String),
  520.     XtOffset(AppDataPtr, icsHost),
  521.     XtRString, (XtPointer) ICS_HOST },
  522.     { "internetChessServerPort", "internetChessServerPort",
  523.     XtRString, sizeof(String),
  524.     XtOffset(AppDataPtr, icsPort), XtRString,
  525.     (XtPointer) ICS_PORT },
  526.     { "internetChessServerCommPort", "internetChessServerCommPort",
  527.     XtRString, sizeof(String),
  528.     XtOffset(AppDataPtr, icsCommPort), XtRString,
  529.     ICS_COMM_PORT },
  530.     { "internetChessServerLogonScript", "internetChessServerLogonScript",
  531.     XtRString, sizeof(String),
  532.     XtOffset(AppDataPtr, icsLogon), XtRString,
  533.     ICS_LOGON },
  534.     { "useTelnet", "useTelnet", XtRBoolean, sizeof(Boolean),
  535.     XtOffset(AppDataPtr, useTelnet), XtRImmediate,
  536.     (XtPointer) False },
  537.     { "telnetProgram", "telnetProgram", XtRString, sizeof(String),
  538.     XtOffset(AppDataPtr, telnetProgram), XtRString, TELNET_PROGRAM },
  539.     { "gateway", "gateway", XtRString, sizeof(String),
  540.     XtOffset(AppDataPtr, gateway), XtRString, "" },
  541.     { "loadGameFile", "loadGameFile", XtRString, sizeof(String),
  542.     XtOffset(AppDataPtr, loadGameFile), XtRString, "" },
  543.     { "loadGameIndex", "loadGameIndex",
  544.     XtRInt, sizeof(int),
  545.     XtOffset(AppDataPtr, loadGameIndex), XtRImmediate,
  546.     (XtPointer) 0 },
  547.     { "saveGameFile", "saveGameFile", XtRString, sizeof(String),
  548.     XtOffset(AppDataPtr, saveGameFile), XtRString, "" },
  549.     { "autoSaveGames", "autoSaveGames", XtRBoolean,
  550.     sizeof(Boolean), XtOffset(AppDataPtr, autoSaveGames),
  551.     XtRImmediate, (XtPointer) False },
  552.     { "loadPositionFile", "loadPositionFile", XtRString,
  553.     sizeof(String), XtOffset(AppDataPtr, loadPositionFile),
  554.     XtRString, "" },
  555.     { "loadPositionIndex", "loadPositionIndex",
  556.     XtRInt, sizeof(int),
  557.     XtOffset(AppDataPtr, loadPositionIndex), XtRImmediate,
  558.     (XtPointer) 1 },
  559.     { "savePositionFile", "savePositionFile", XtRString,
  560.     sizeof(String), XtOffset(AppDataPtr, savePositionFile),
  561.     XtRString, "" },
  562.     { "matchMode", "matchMode", XtRBoolean, sizeof(Boolean),
  563.     XtOffset(AppDataPtr, matchMode), XtRImmediate, (XtPointer) False },
  564.     { "monoMode", "monoMode", XtRBoolean, sizeof(Boolean),
  565.     XtOffset(AppDataPtr, monoMode), XtRImmediate,
  566.     (XtPointer) False },
  567.     { "debugMode", "debugMode", XtRBoolean, sizeof(Boolean),
  568.     XtOffset(AppDataPtr, debugMode), XtRImmediate,
  569.     (XtPointer) False },
  570.     { "clockMode", "clockMode", XtRBoolean, sizeof(Boolean),
  571.     XtOffset(AppDataPtr, clockMode), XtRImmediate,
  572.     (XtPointer) True },
  573.     { "boardSize", "boardSize", XtRString, sizeof(String),
  574.     XtOffset(AppDataPtr, boardSize), XtRString, "" },
  575.     { "searchTime", "searchTime", XtRString, sizeof(String),
  576.     XtOffset(AppDataPtr, searchTime), XtRString,
  577.     (XtPointer) "" },
  578.     { "searchDepth", "searchDepth", XtRInt, sizeof(int),
  579.     XtOffset(AppDataPtr, searchDepth), XtRImmediate, 
  580.     (XtPointer) 0 },
  581.     { "showCoords", "showCoords", XtRBoolean, sizeof(Boolean),
  582.     XtOffset(AppDataPtr, showCoords), XtRImmediate,
  583.     (XtPointer) False },
  584.     { "showThinking", "showThinking", XtRBoolean, sizeof(Boolean),
  585.     XtOffset(AppDataPtr, showThinking), XtRImmediate,
  586.     (XtPointer) False },
  587.     { "clockFont", "clockFont", XtRString, sizeof(String),
  588.     XtOffset(AppDataPtr, clockFont), XtRString, CLOCK_FONT },
  589.     { "coordFont", "coordFont", XtRString, sizeof(String),
  590.     XtOffset(AppDataPtr, coordFont), XtRString, COORD_FONT },
  591.     { "ringBellAfterMoves", "ringBellAfterMoves",
  592.     XtRBoolean, sizeof(Boolean),
  593.     XtOffset(AppDataPtr, ringBellAfterMoves),
  594.     XtRImmediate, (XtPointer) False    },
  595.     { "autoCallFlag", "autoCallFlag", XtRBoolean,
  596.     sizeof(Boolean), XtOffset(AppDataPtr, autoCallFlag),
  597.     XtRImmediate, (XtPointer) False },
  598.     { "autoObserve", "autoObserve", XtRBoolean,
  599.     sizeof(Boolean), XtOffset(AppDataPtr, autoObserve),
  600.     XtRImmediate, (XtPointer) False },
  601.     { "autoComment", "autoComment", XtRBoolean,
  602.     sizeof(Boolean), XtOffset(AppDataPtr, autoComment),
  603.     XtRImmediate, (XtPointer) False },
  604.     { "flipView", "flipView", XtRBoolean,
  605.     sizeof(Boolean), XtOffset(AppDataPtr, flipView),
  606.     XtRImmediate, (XtPointer) False },
  607.     { "cmail", "cmailGameName", XtRString, sizeof(String),
  608.     XtOffset(AppDataPtr, cmailGameName), XtRString, "" },
  609.     { "alwaysPromoteToQueen", "alwaysPromoteToQueen", XtRBoolean,
  610.     sizeof(Boolean), XtOffset(AppDataPtr, alwaysPromoteToQueen),
  611.     XtRImmediate, (XtPointer) False },
  612.     { "oldSaveStyle", "oldSaveStyle", XtRBoolean,
  613.     sizeof(Boolean), XtOffset(AppDataPtr, oldSaveStyle),
  614.     XtRImmediate, (XtPointer) False },
  615.     { "quietPlay", "quietPlay", XtRBoolean,
  616.     sizeof(Boolean), XtOffset(AppDataPtr, quietPlay),
  617.     XtRImmediate, (XtPointer) False },
  618.     { "borderXoffset", "borderXoffset", XtRInt, sizeof(int),
  619.     XtOffset(AppDataPtr, borderXoffset), XtRImmediate,
  620.     (XtPointer) BORDER_X_OFFSET },
  621.     { "borderYoffset", "borderYOffset", XtRInt, sizeof(int),
  622.     XtOffset(AppDataPtr, borderYoffset), XtRImmediate,
  623.     (XtPointer) BORDER_Y_OFFSET },
  624.     { "titleInWindow", "titleInWindow", XtRBoolean,
  625.     sizeof(Boolean), XtOffset(AppDataPtr, titleInWindow),
  626.     XtRImmediate, (XtPointer) False },
  627. #ifdef ZIPPY
  628.     { "zippyTalk", "zippyTalk", XtRBoolean,
  629.     sizeof(Boolean), XtOffset(AppDataPtr, zippyTalk),
  630.     XtRImmediate, (XtPointer) False },
  631.     { "zippyPlay", "zippyPlay", XtRBoolean,
  632.     sizeof(Boolean), XtOffset(AppDataPtr, zippyPlay),
  633.     XtRImmediate, (XtPointer) False },
  634. #endif
  635. };
  636.  
  637. Pixmap *pieceToSolid[] = {
  638.     &solidPawnBitmap, &solidRookBitmap, &solidKnightBitmap,
  639.     &solidBishopBitmap, &solidQueenBitmap, &solidKingBitmap,
  640.     &solidPawnBitmap, &solidRookBitmap, &solidKnightBitmap,
  641.     &solidBishopBitmap, &solidQueenBitmap, &solidKingBitmap
  642.   };
  643.  
  644. Pixmap *pieceToOutline[] = {
  645.     &outlinePawnBitmap, &outlineRookBitmap, &outlineKnightBitmap,
  646.     &outlineBishopBitmap, &outlineQueenBitmap, &outlineKingBitmap,
  647.     &outlinePawnBitmap, &outlineRookBitmap, &outlineKnightBitmap,
  648.     &outlineBishopBitmap, &outlineQueenBitmap, &outlineKingBitmap
  649.   };
  650.  
  651. XrmOptionDescRec shellOptions[] = {
  652.     { "-whitePieceColor", "whitePieceColor", XrmoptionSepArg, NULL },
  653.     { "-blackPieceColor", "blackPieceColor", XrmoptionSepArg, NULL },
  654.     { "-lightSquareColor", "lightSquareColor", XrmoptionSepArg, NULL },
  655.     { "-darkSquareColor", "darkSquareColor", XrmoptionSepArg, NULL },
  656.     { "-movesPerSession", "movesPerSession", XrmoptionSepArg, NULL },
  657.     { "-mps", "movesPerSession", XrmoptionSepArg, NULL },
  658.     { "-initString", "initString", XrmoptionSepArg, NULL },
  659.     { "-whiteString", "whiteString", XrmoptionSepArg, NULL },
  660.     { "-blackString", "blackString", XrmoptionSepArg, NULL },
  661.     { "-firstChessProgram", "firstChessProgram", XrmoptionSepArg, NULL },
  662.     { "-fcp", "firstChessProgram", XrmoptionSepArg, NULL },
  663.     { "-secondChessProgram", "secondChessProgram", XrmoptionSepArg, NULL },
  664.     { "-scp", "secondChessProgram", XrmoptionSepArg, NULL },
  665.     { "-noChessProgram", "noChessProgram", XrmoptionSepArg, NULL },
  666.     { "-ncp", "noChessProgram", XrmoptionNoArg, "True" },
  667.     { "-xncp", "noChessProgram", XrmoptionNoArg, "False" },
  668.     { "-firstHost", "firstHost", XrmoptionSepArg, NULL },
  669.     { "-fh", "firstHost", XrmoptionSepArg, NULL },
  670.     { "-secondHost", "secondHost", XrmoptionSepArg, NULL },
  671.     { "-sh", "secondHost", XrmoptionSepArg, NULL },
  672.     { "-bitmapDirectory", "bitmapDirectory", XrmoptionSepArg, NULL },
  673.     { "-bm", "bitmapDirectory", XrmoptionSepArg, NULL },
  674.     { "-remoteShell", "remoteShell", XrmoptionSepArg, NULL },
  675.     { "-rsh", "remoteShell", XrmoptionSepArg, NULL },
  676.     { "-remoteUser", "remoteUser", XrmoptionSepArg, NULL },
  677.     { "-ruser", "remoteUser", XrmoptionSepArg, NULL },
  678.     { "-timeDelay", "timeDelay", XrmoptionSepArg, NULL },
  679.     { "-td", "timeDelay", XrmoptionSepArg, NULL },
  680.     { "-timeControl", "timeControl", XrmoptionSepArg, NULL },
  681.     { "-tc", "timeControl", XrmoptionSepArg, NULL },
  682.     { "-internetChessServerMode", "internetChessServerMode",
  683.     XrmoptionSepArg, NULL },
  684.     { "-ics", "internetChessServerMode", XrmoptionNoArg, "True" },
  685.     { "-xics", "internetChessServerMode", XrmoptionNoArg, "False" },
  686.     { "-internetChessServerHost", "internetChessServerHost",
  687.     XrmoptionSepArg, NULL },
  688.     { "-icshost", "internetChessServerHost", XrmoptionSepArg, NULL },
  689.     { "-internetChessServerPort", "internetChessServerPort",
  690.     XrmoptionSepArg, NULL },
  691.     { "-icsport", "internetChessServerPort", XrmoptionSepArg, NULL },
  692.     { "-internetChessServerCommPort", "internetChessServerCommPort",
  693.     XrmoptionSepArg, NULL },
  694.     { "-icscomm", "internetChessServerCommPort", XrmoptionSepArg, NULL },
  695.     { "-internetChessServerLogonScript", "internetChessServerLogonScript",
  696.     XrmoptionSepArg, NULL },
  697.     { "-icslogon", "internetChessServerLogonScript", XrmoptionSepArg, NULL },
  698.     { "-useTelnet", "useTelnet", XrmoptionSepArg, NULL },
  699.     { "-telnet", "useTelnet", XrmoptionNoArg, "True" },
  700.     { "-xtelnet", "useTelnet", XrmoptionNoArg, "False" },
  701.     { "-telnetProgram", "telnetProgram", XrmoptionSepArg, NULL },
  702.     { "-gateway", "gateway", XrmoptionSepArg, NULL },
  703.     { "-loadGameFile", "loadGameFile", XrmoptionSepArg, NULL },
  704.     { "-lgf", "loadGameFile", XrmoptionSepArg, NULL },
  705.     { "-loadGameIndex", "loadGameIndex", XrmoptionSepArg, NULL },
  706.     { "-lgi", "loadGameIndex", XrmoptionSepArg, NULL },
  707.     { "-saveGameFile", "saveGameFile", XrmoptionSepArg, NULL },
  708.     { "-sgf", "saveGameFile", XrmoptionSepArg, NULL },
  709.     { "-autoSaveGames", "autoSaveGames", XrmoptionSepArg, NULL },
  710.     { "-autosave", "autoSaveGames", XrmoptionNoArg, "True" },
  711.     { "-xautosave", "autoSaveGames", XrmoptionNoArg, "False" },
  712.     { "-loadPositionFile", "loadPositionFile", XrmoptionSepArg, NULL },
  713.     { "-lpf", "loadPositionFile", XrmoptionSepArg, NULL },
  714.     { "-loadPositionIndex", "loadPositionIndex", XrmoptionSepArg, NULL },
  715.     { "-lpi", "loadPositionIndex", XrmoptionSepArg, NULL },
  716.     { "-savePositionFile", "savePositionFile", XrmoptionSepArg, NULL },
  717.     { "-spf", "savePositionFile", XrmoptionSepArg, NULL },
  718.     { "-matchMode", "matchMode", XrmoptionSepArg, NULL },
  719.     { "-mm", "matchMode", XrmoptionNoArg, "True" },
  720.     { "-xmm", "matchMode", XrmoptionNoArg, "False" },
  721.     { "-monoMode", "monoMode", XrmoptionSepArg, NULL },
  722.     { "-mono", "monoMode", XrmoptionNoArg, "True" },
  723.     { "-xmono", "monoMode", XrmoptionNoArg, "False" },
  724.     { "-debugMode", "debugMode", XrmoptionSepArg, NULL },
  725.     { "-debug", "debugMode", XrmoptionNoArg, "True" },
  726.     { "-xdebug", "debugMode", XrmoptionNoArg, "False" },
  727.     { "-clockMode", "clockMode", XrmoptionSepArg, NULL },
  728.     { "-clock", "clockMode", XrmoptionNoArg, "True" },
  729.     { "-xclock", "clockMode", XrmoptionNoArg, "False" },
  730.     { "-boardSize", "boardSize", XrmoptionSepArg, NULL },
  731.     { "-size", "boardSize", XrmoptionSepArg, NULL },
  732.     { "-searchTime", "searchTime", XrmoptionSepArg, NULL },
  733.     { "-st", "searchTime", XrmoptionSepArg, NULL },
  734.     { "-searchDepth", "searchDepth", XrmoptionSepArg, NULL },
  735.     { "-sd", "searchDepth", XrmoptionSepArg, NULL },
  736.     { "-showCoords", "showCoords", XrmoptionSepArg, NULL },
  737.     { "-coords", "showCoords", XrmoptionNoArg, "True" },
  738.     { "-xcoords", "showCoords", XrmoptionNoArg, "False" },
  739.     { "-showThinking", "showThinking", XrmoptionSepArg, NULL },
  740.     { "-thinking", "showThinking", XrmoptionNoArg, "True" },
  741.     { "-xthinking", "showThinking", XrmoptionNoArg, "False" },
  742.     { "-clockFont", "clockFont", XrmoptionSepArg, NULL },
  743.     { "-coordFont", "coordFont", XrmoptionSepArg, NULL },
  744.     { "-ringBellAfterMoves", "ringBellAfterMoves", XrmoptionSepArg, NULL },
  745.     { "-bell", "ringBellAfterMoves", XrmoptionNoArg, "True" },
  746.     { "-xbell", "ringBellAfterMoves", XrmoptionNoArg, "False" },
  747.     { "-autoCallFlag", "autoCallFlag", XrmoptionSepArg, NULL },
  748.     { "-autoflag", "autoCallFlag", XrmoptionNoArg, "True" },
  749.     { "-xautoflag", "autoCallFlag", XrmoptionNoArg, "False" },
  750.     { "-autoObserve", "autoObserve", XrmoptionSepArg, NULL },
  751.     { "-autobs", "autoObserve", XrmoptionNoArg, "True" },
  752.     { "-xautobs", "autoObserve", XrmoptionNoArg, "False" },
  753.     { "-autoComment", "autoComment", XrmoptionSepArg, NULL },
  754.     { "-autocomm", "autoComment", XrmoptionNoArg, "True" },
  755.     { "-xautocomm", "autoComment", XrmoptionNoArg, "False" },
  756.     { "-flipView", "flipView", XrmoptionSepArg, NULL },
  757.     { "-flip", "flipView", XrmoptionNoArg, "True" },
  758.     { "-xflip", "flipView", XrmoptionNoArg, "False" },
  759.     { "-cmail", "cmailGameName", XrmoptionSepArg, NULL },
  760.     { "-alwaysPromoteToQueen", "alwaysPromoteToQueen",
  761.     XrmoptionSepArg, NULL },
  762.     { "-queen", "alwaysPromoteToQueen", XrmoptionNoArg, "True" },
  763.     { "-xqueen", "alwaysPromoteToQueen", XrmoptionNoArg, "False" },
  764.     { "-oldSaveStyle", "oldSaveStyle", XrmoptionSepArg, NULL },
  765.     { "-oldsave", "oldSaveStyle", XrmoptionNoArg, "True" },
  766.     { "-xoldsave", "oldSaveStyle", XrmoptionNoArg, "False" },
  767.     { "-quietPlay", "quietPlay", XrmoptionSepArg, NULL },
  768.     { "-quiet", "quietPlay", XrmoptionNoArg, "True" },
  769.     { "-xquiet", "quietPlay", XrmoptionNoArg, "False" },
  770.     { "-borderXoffset", "borderXoffset", XrmoptionSepArg, NULL },
  771.     { "-borderYoffset", "borderYoffset", XrmoptionSepArg, NULL },
  772.     { "-titleInWindow", "titleInWindow", XrmoptionSepArg, NULL },
  773.     { "-title", "titleInWindow", XrmoptionNoArg, "True" },
  774.     { "-xtitle", "titleInWindow", XrmoptionNoArg, "False" },
  775. #ifdef ZIPPY
  776.     { "-zippyTalk", "zippyTalk", XrmoptionSepArg, NULL },
  777.     { "-zt", "zippyTalk", XrmoptionNoArg, "True" },
  778.     { "-xzt", "zippyTalk", XrmoptionNoArg, "False" },
  779.     { "-zippyPlay", "zippyPlay", XrmoptionSepArg, NULL },
  780.     { "-zp", "zippyPlay", XrmoptionNoArg, "True" },
  781.     { "-xzp", "zippyPlay", XrmoptionNoArg, "False" },
  782. #endif
  783. };
  784.  
  785.  
  786. XtActionsRec boardActions[] = {
  787.     { "DrawPosition", DrawPositionProc },
  788.     { "HandleUserMove", HandleUserMove },
  789.     { "FileNameAction", FileNameAction },
  790.     { "PieceMenuPopup", PieceMenuPopup },
  791.     { "WhiteClock", WhiteClock },
  792.     { "BlackClock", BlackClock },
  793.     { "Iconify", Iconify },
  794.     { "ResetProc", ResetProc },
  795.     { "LoadGameProc", LoadGameProc },
  796.     { "LoadNextGameProc", LoadNextGameProc },
  797.     { "LoadPrevGameProc", LoadPrevGameProc },
  798.     { "LoadSelectedProc", LoadSelectedProc },
  799.     { "ReloadGameProc", ReloadGameProc },
  800.     { "LoadPositionProc", LoadPositionProc },
  801.     { "SaveGameProc", SaveGameProc },
  802.     { "SavePositionProc", SavePositionProc },
  803.     { "MailMoveProc", MailMoveProc },
  804.     { "ReloadCmailMsgProc", ReloadCmailMsgProc },
  805.     { "QuitProc", QuitProc },
  806.     { "MachineWhiteProc", MachineWhiteProc },
  807.     { "MachineBlackProc", MachineBlackProc },
  808.     { "TwoMachinesProc", TwoMachinesProc },
  809.     { "IcsClientProc", IcsClientProc },
  810.     { "EditGameProc", EditGameProc },
  811.     { "EditPositionProc", EditPositionProc },
  812.     { "ShowGameListProc", ShowGameListProc },
  813.     { "EditTagsProc", EditCommentProc },
  814.     { "EditCommentProc", EditCommentProc },
  815.     { "PauseProc", PauseProc },
  816.     { "AcceptProc", AcceptProc },
  817.     { "DeclineProc", DeclineProc },
  818.     { "CallFlagProc", CallFlagProc },
  819.     { "DrawProc", DrawProc },
  820.     { "AdjournProc", AdjournProc },
  821.     { "AbortProc", AbortProc },
  822.     { "ResignProc", ResignProc },
  823.     { "StopObservingProc", StopObservingProc },
  824.     { "StopExaminingProc", StopExaminingProc },
  825.     { "BackwardProc", BackwardProc },
  826.     { "ForwardProc", ForwardProc },
  827.     { "ToStartProc", ToStartProc },
  828.     { "ToEndProc", ToEndProc },
  829.     { "RevertProc", RevertProc },
  830.     { "TruncateGameProc", TruncateGameProc },
  831.     { "MoveNowProc", MoveNowProc },
  832.     { "RetractMoveProc", RetractMoveProc },
  833.     { "AlwaysQueenProc", AlwaysQueenProc },
  834.     { "AutoflagProc", AutoflagProc },
  835.     { "AutobsProc", AutobsProc },
  836.     { "AutosaveProc", AutosaveProc },
  837.     { "BellProc", BellProc },
  838.     { "FlipViewProc", FlipViewProc },
  839.     { "OldSaveStyleProc", OldSaveStyleProc },
  840.     { "QuietPlayProc", QuietPlayProc },
  841.     { "ShowCoordsProc", ShowCoordsProc },
  842.     { "ShowThinkingProc", ShowThinkingProc },
  843.     { "HintProc", HintProc },
  844.     { "BookProc", BookProc },
  845.     { "AboutGameProc", AboutGameProc },
  846.     { "AboutProc", AboutProc },
  847.     { "NothingProc", NothingProc },
  848. };
  849.      
  850. char globalTranslations[] =
  851.   "Shift<Key>r: ResignProc() \n \
  852.    <Key>r: ResetProc() \n \
  853.    <Key>g: LoadGameProc() \n \
  854.    Shift<Key>n: LoadNextGameProc() \n \
  855.    Shift<Key>p: LoadPrevGameProc() \n \
  856.    <Key>q: QuitProc() \n \
  857.    Shift<Key>f: ToEndProc() \n \
  858.    <Key>f: ForwardProc() \n \
  859.    Shift<Key>b: ToStartProc() \n \
  860.    <Key>b: BackwardProc() \n \
  861.    <Key>p: PauseProc() \n \
  862.    <Key>d: DrawProc() \n \
  863.    <Key>t: CallFlagProc() \n \
  864.    <Key>i: Iconify() \n \
  865.    <Key>c: Iconify() \n";
  866.  
  867. char boardTranslations[] =
  868.   "<Expose>: DrawPosition() \n \
  869.    <Btn1Down>: HandleUserMove() \n \
  870.    <Btn1Up>: HandleUserMove() \n \
  871.    <Btn2Down>: XawPositionSimpleMenu(menuW) PieceMenuPopup(menuW) \n \
  872.    <Btn3Down>: XawPositionSimpleMenu(menuB) PieceMenuPopup(menuB) \n \
  873.    <Message>WM_PROTOCOLS: QuitProc() \n";
  874.      
  875. char whiteTranslations[] = "<BtnDown>: WhiteClock()\n";
  876. char blackTranslations[] = "<BtnDown>: BlackClock()\n";
  877.      
  878. String xboardResources[] = {
  879.     DEFAULT_FONT,
  880.     "*Dialog*value.translations: #override \\n <Key>Return: FileNameAction()",
  881.     NULL
  882.   };
  883.      
  884. void main(argc, argv)
  885.      int argc;
  886.      char **argv;
  887. {
  888.     int i, j, clockFontPxlSize, coordFontPxlSize;
  889.     XSetWindowAttributes window_attributes;
  890.     Arg args[16];
  891.     Dimension timerWidth, boardWidth, w, h, sep, bor, wr, hr;
  892.     XrmValue vFrom, vTo;
  893.     XtTranslations tr;
  894.     XtGeometryResult gres;
  895.  
  896.     setbuf(stdout, NULL);
  897.     setbuf(stderr, NULL);
  898.     fromUserFP = stdin;
  899.     toUserFP = stdout;
  900.     debugFP = stderr;
  901.     
  902.     programName = strrchr(argv[0], '/');
  903.     if (programName == NULL)
  904.       programName = argv[0];
  905.     else
  906.       programName++;
  907.     
  908.     shellWidget =
  909.       XtAppInitialize(&appContext, "XBoard", shellOptions,
  910.               XtNumber(shellOptions),
  911.               &argc, argv, xboardResources, NULL, 0);
  912.     if (argc > 1)
  913.       Usage();
  914.     
  915.     if ((chessDir = (char *) getenv("CHESSDIR")) == NULL) {
  916.     chessDir = ".";
  917.     } else {
  918.     if (chdir(chessDir) != 0) {
  919.         fprintf(stderr, "%s: can't cd to CHESSDIR: ", programName);
  920.         perror(chessDir);
  921.         exit(1);
  922.     }
  923.     }
  924.     
  925.     XtGetApplicationResources(shellWidget, (XtPointer) &appData,
  926.                   clientResources, XtNumber(clientResources),
  927.                   NULL, 0);
  928.  
  929.     InitBackEnd1();
  930.  
  931.     xDisplay = XtDisplay(shellWidget);
  932.     xScreen = DefaultScreen(xDisplay);
  933.  
  934.     /*
  935.      * Determine boardSize
  936.      */
  937.     if (*appData.boardSize == NULLCHAR) {
  938.     if (((DisplayWidth(xDisplay, xScreen) < 800) ||
  939.          (DisplayHeight(xDisplay, xScreen) < 800)))
  940.       boardSize = Medium;
  941.     else
  942.       boardSize = Large;
  943.     } else if (StrCaseCmp(appData.boardSize, "Large") == 0) {
  944.     boardSize = Large;
  945.     } else if (StrCaseCmp(appData.boardSize, "Medium") == 0) {
  946.     boardSize = Medium;
  947.     } else if (StrCaseCmp(appData.boardSize, "Small") == 0) {
  948.     boardSize = Small;
  949.     } else {
  950.     fprintf(stderr, "%s: bad boardSize option %s\n",
  951.         programName, appData.boardSize);
  952.     Usage();
  953.     }
  954.     switch (boardSize) {
  955.       case Small:
  956.     squareSize = SMALL_SQUARE_SIZE;
  957.     lineGap = SMALL_LINE_GAP;
  958.     clockFontPxlSize = 20;
  959.     coordFontPxlSize = 10;
  960.     break;
  961.       case Medium:
  962.     squareSize = MEDIUM_SQUARE_SIZE;
  963.     lineGap = MEDIUM_LINE_GAP;
  964.     clockFontPxlSize = 34;
  965.     coordFontPxlSize = 12;
  966.     break;
  967.       case Large:
  968.       default:
  969.     squareSize = LARGE_SQUARE_SIZE;
  970.     lineGap = LARGE_LINE_GAP;
  971.     clockFontPxlSize = 34;
  972.     coordFontPxlSize = 14;
  973.     break;
  974.     }
  975.     boardWidth = lineGap + BOARD_SIZE * (squareSize + lineGap);
  976.     XtSetArg(boardArgs[1], XtNwidth, boardWidth);
  977.     XtSetArg(boardArgs[2], XtNheight,
  978.          lineGap + BOARD_SIZE * (squareSize + lineGap));
  979.  
  980.     /*
  981.      * Determine what fonts to use.
  982.      */
  983.     appData.clockFont = FindFont(appData.clockFont, clockFontPxlSize);
  984.     clockFontID = XLoadFont(xDisplay, appData.clockFont);
  985.     clockFontStruct = XQueryFont(xDisplay, clockFontID);
  986.     appData.coordFont = FindFont(appData.coordFont, coordFontPxlSize);
  987.     coordFontID = XLoadFont(xDisplay, appData.coordFont);
  988.     coordFontStruct = XQueryFont(xDisplay, coordFontID);
  989.  
  990.     /*
  991.      * Detect if there are not enough colors are available and adapt.
  992.      */
  993.     if (DefaultDepth(xDisplay, xScreen) <= 2)
  994.       appData.monoMode = True;
  995.  
  996.     if (!appData.monoMode) {
  997.     vFrom.addr = (caddr_t) appData.lightSquareColor;
  998.     vFrom.size = strlen(appData.lightSquareColor);
  999.     XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
  1000.     if (vTo.addr == NULL)
  1001.       appData.monoMode = True;
  1002.     else
  1003.       lightSquareColor = *(Pixel *) vTo.addr;
  1004.     }
  1005.     if (!appData.monoMode) {
  1006.     vFrom.addr = (caddr_t) appData.darkSquareColor;
  1007.     vFrom.size = strlen(appData.darkSquareColor);
  1008.     XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
  1009.     if (vTo.addr == NULL)
  1010.       appData.monoMode = True;
  1011.     else
  1012.       darkSquareColor = *(Pixel *) vTo.addr;
  1013.     }
  1014.     if (!appData.monoMode) {
  1015.     vFrom.addr = (caddr_t) appData.whitePieceColor;
  1016.     vFrom.size = strlen(appData.whitePieceColor);
  1017.     XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
  1018.     if (vTo.addr == NULL)
  1019.       appData.monoMode = True;
  1020.     else
  1021.       whitePieceColor = *(Pixel *) vTo.addr;
  1022.     }
  1023.     if (!appData.monoMode) {
  1024.     vFrom.addr = (caddr_t) appData.blackPieceColor;
  1025.     vFrom.size = strlen(appData.blackPieceColor);
  1026.     XtConvert(shellWidget, XtRString, &vFrom, XtRPixel, &vTo);
  1027.     if (vTo.addr == NULL)
  1028.       appData.monoMode = True;
  1029.     else
  1030.       blackPieceColor = *(Pixel *) vTo.addr;
  1031.     }
  1032.  
  1033.     if (appData.monoMode && appData.debugMode) {
  1034.     fprintf(stderr, "white pixel = 0x%lx, black pixel = 0x%lx\n",
  1035.         (unsigned long) XWhitePixel(xDisplay, xScreen),
  1036.         (unsigned long) XBlackPixel(xDisplay, xScreen));
  1037.     }
  1038.     
  1039.     XtAppAddActions(appContext, boardActions, XtNumber(boardActions));
  1040.     
  1041.     /*
  1042.      * widget hierarchy
  1043.      */
  1044.     formWidget =
  1045.       XtCreateManagedWidget("form", formWidgetClass, shellWidget, NULL, 0);
  1046.     XtSetArg(args[0], XtNdefaultDistance, &sep);
  1047.     XtGetValues(formWidget, args, 1);
  1048.     
  1049.     j = 0;
  1050.     widgetList[j++] = menuBarWidget = CreateMenuBar(menuBar);
  1051.  
  1052.     widgetList[j++] = whiteTimerWidget =
  1053.       XtCreateWidget("whiteTime", labelWidgetClass,
  1054.              formWidget, timerArgs, XtNumber(timerArgs));
  1055.     XtSetArg(args[0], XtNfont, clockFontStruct);
  1056.     XtSetValues(whiteTimerWidget, args, 1);
  1057.     
  1058.     widgetList[j++] = blackTimerWidget =
  1059.       XtCreateWidget("blackTime", labelWidgetClass,
  1060.              formWidget, timerArgs, XtNumber(timerArgs));
  1061.     XtSetArg(args[0], XtNfont, clockFontStruct);
  1062.     XtSetValues(blackTimerWidget, args, 1);
  1063.     
  1064.     if (appData.titleInWindow) {
  1065.     widgetList[j++] = titleWidget = 
  1066.       XtCreateWidget("title", labelWidgetClass, formWidget,
  1067.              titleArgs, XtNumber(titleArgs));
  1068.     }
  1069.  
  1070.     widgetList[j++] = buttonBarWidget = CreateButtonBar(buttonBar);
  1071.  
  1072.     widgetList[j++] = messageWidget =
  1073.       XtCreateWidget("message", labelWidgetClass, formWidget,
  1074.              messageArgs, XtNumber(messageArgs));
  1075.     
  1076.     widgetList[j++] = boardWidget =
  1077.       XtCreateWidget("board", widgetClass, formWidget, boardArgs,
  1078.              XtNumber(boardArgs));
  1079.     
  1080.     XtManageChildren(widgetList, j);
  1081.     
  1082.     timerWidth = (boardWidth - sep) / 2;
  1083.     XtSetArg(args[0], XtNwidth, timerWidth);
  1084.     XtSetValues(whiteTimerWidget, args, 1);
  1085.     XtSetValues(blackTimerWidget, args, 1);
  1086.     
  1087.     XtSetArg(args[0], XtNbackground, &timerBackgroundPixel);
  1088.     XtSetArg(args[1], XtNforeground, &timerForegroundPixel);
  1089.     XtGetValues(whiteTimerWidget, args, 2);
  1090.     
  1091.     XtSetArg(args[0], XtNbackground, &buttonBackgroundPixel);
  1092.     XtSetArg(args[1], XtNforeground, &buttonForegroundPixel);
  1093.     XtGetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
  1094.  
  1095.     /*
  1096.      * formWidget uses these constraints but they are stored
  1097.      * in the children.
  1098.      */
  1099.     i = 0;
  1100.     XtSetArg(args[i], XtNfromHoriz, 0); i++;
  1101.     XtSetValues(menuBarWidget, args, i);
  1102.     if (appData.titleInWindow) {
  1103.     if (boardSize == Small) {
  1104.         i = 0;
  1105.         XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
  1106.         XtSetValues(whiteTimerWidget, args, i);
  1107.         i = 0;
  1108.         XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
  1109.         XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
  1110.         XtSetValues(blackTimerWidget, args, i);
  1111.         i = 0;
  1112.         XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
  1113.             XtSetArg(args[i], XtNjustify, XtJustifyLeft); i++;
  1114.         XtSetValues(titleWidget, args, i);
  1115.         i = 0;
  1116.         XtSetArg(args[i], XtNfromVert, titleWidget); i++;
  1117.         XtSetValues(messageWidget, args, i);
  1118.         i = 0;
  1119.         XtSetArg(args[i], XtNfromVert, titleWidget); i++;
  1120.         XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
  1121.         XtSetValues(buttonBarWidget, args, i);
  1122.     } else {
  1123.         i = 0;
  1124.         XtSetArg(args[i], XtNfromVert, titleWidget); i++;
  1125.         XtSetValues(whiteTimerWidget, args, i);
  1126.         i = 0;
  1127.         XtSetArg(args[i], XtNfromVert, titleWidget); i++;
  1128.         XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
  1129.         XtSetValues(blackTimerWidget, args, i);
  1130.         i = 0;
  1131.         XtSetArg(args[i], XtNfromHoriz, menuBarWidget); i++;
  1132.         XtSetValues(titleWidget, args, i);
  1133.         i = 0;
  1134.         XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
  1135.         XtSetValues(messageWidget, args, i);
  1136.         i = 0;
  1137.         XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
  1138.         XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
  1139.         XtSetValues(buttonBarWidget, args, i);
  1140.     }
  1141.     } else {
  1142.     i = 0;
  1143.     XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
  1144.     XtSetValues(whiteTimerWidget, args, i);
  1145.     i = 0;
  1146.     XtSetArg(args[i], XtNfromVert, menuBarWidget); i++;
  1147.     XtSetArg(args[i], XtNfromHoriz, whiteTimerWidget); i++;
  1148.     XtSetValues(blackTimerWidget, args, i);
  1149.     i = 0;
  1150.     XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
  1151.     XtSetValues(messageWidget, args, i);
  1152.     i = 0;
  1153.     XtSetArg(args[i], XtNfromVert, whiteTimerWidget); i++;
  1154.     XtSetArg(args[i], XtNfromHoriz, messageWidget); i++;
  1155.     XtSetValues(buttonBarWidget, args, i);
  1156.     }
  1157.     i = 0;
  1158.     XtSetArg(args[0], XtNfromVert, messageWidget);
  1159.     XtSetValues(boardWidget, args, 1);
  1160.     
  1161.     XtRealizeWidget(shellWidget);
  1162.  
  1163.     /*
  1164.      * Correct the width of the message and title widgets.
  1165.      * It is not known why some systems need the extra fudge term.
  1166.      * The value "2" is probably larger than needed.
  1167.      */
  1168. #define WIDTH_FUDGE 2
  1169.     i = 0;
  1170.     XtSetArg(args[i], XtNwidth, &w);  i++;
  1171.     XtGetValues(buttonBarWidget, args, i);
  1172.     i = 0;
  1173.     XtSetArg(args[i], XtNborderWidth, &bor);  i++;
  1174.     XtSetArg(args[i], XtNheight, &h);  i++;
  1175.     XtGetValues(messageWidget, args, i);
  1176.  
  1177.     w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
  1178.     gres = XtMakeResizeRequest(messageWidget, w, h, &wr, &hr);
  1179.     if (gres != XtGeometryYes) {
  1180.     fprintf(stderr, "%s: messageWidget geometry error %d %d %d %d %d\n",
  1181.         programName, gres, w, h, wr, hr);
  1182.     }
  1183.  
  1184.     if (appData.titleInWindow) {
  1185.     i = 0;
  1186.     XtSetArg(args[i], XtNborderWidth, &bor); i++;
  1187.     XtSetArg(args[i], XtNheight, &h);  i++;
  1188.     XtGetValues(titleWidget, args, i);
  1189.     if (boardSize == Small) {
  1190.         w = boardWidth - 2*bor;
  1191.     } else {
  1192.         XtSetArg(args[0], XtNwidth, &w);
  1193.         XtGetValues(menuBarWidget, args, 1);
  1194.         w = boardWidth - w - sep - 2*bor - WIDTH_FUDGE;
  1195.     }
  1196.  
  1197.     gres = XtMakeResizeRequest(titleWidget, w, h, &wr, &hr);
  1198.     if (gres != XtGeometryYes) {
  1199.         fprintf(stderr,
  1200.             "%s: titleWidget geometry error %d %d %d %d %d\n",
  1201.             programName, gres, w, h, wr, hr);
  1202.     }
  1203.     }
  1204.     xBoardWindow = XtWindow(boardWidget);
  1205.     
  1206.     /* 
  1207.      * Create X checkmark bitmap and initialize option menu checks.
  1208.      */
  1209.     ReadBitmap(&xMarkPixmap, "checkmark.bm",
  1210.            checkmark_bits, checkmark_width, checkmark_height);
  1211.     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
  1212.     if (appData.alwaysPromoteToQueen) {
  1213.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
  1214.             args, 1);
  1215.     }
  1216.     if (appData.autoComment) {
  1217.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
  1218.             args, 1);
  1219.     }
  1220.     if (appData.autoCallFlag) {
  1221.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
  1222.             args, 1);
  1223.     }
  1224.     if (appData.autoObserve) {
  1225.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
  1226.             args, 1);
  1227.     }
  1228.     if (appData.autoSaveGames) {
  1229.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
  1230.             args, 1);
  1231.     }
  1232.     if (appData.saveGameFile[0] != NULLCHAR) {
  1233.     /* Can't turn this off from menu */
  1234.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
  1235.             args, 1);
  1236.     XtSetSensitive(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
  1237.                False);
  1238.  
  1239.     }
  1240.     if (appData.ringBellAfterMoves) {
  1241.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Bell"),
  1242.             args, 1);
  1243.     }
  1244.     if (appData.showCoords) {
  1245.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
  1246.             args, 1);
  1247.     }
  1248.     if (appData.showThinking) {
  1249.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),
  1250.             args, 1);
  1251.     }
  1252.     if (appData.oldSaveStyle) {
  1253.     XtSetValues(XtNameToWidget(menuBarWidget,
  1254.                    "menuOptions.Old Save Style"), args, 1);
  1255.     }
  1256.     if (appData.quietPlay) {
  1257.     XtSetValues(XtNameToWidget(menuBarWidget,
  1258.                    "menuOptions.Quiet Play"), args, 1);
  1259.     }
  1260.  
  1261.     /*
  1262.      * Create an icon.
  1263.      */
  1264.     ReadBitmap(&wIconPixmap, "icon_white.bm",
  1265.            icon_white_bits, icon_white_width, icon_white_height);
  1266.     ReadBitmap(&bIconPixmap, "icon_black.bm",
  1267.            icon_black_bits, icon_black_width, icon_black_height);
  1268.     iconPixmap = wIconPixmap;
  1269.     i = 0;
  1270.     XtSetArg(args[i], XtNiconPixmap, iconPixmap);  i++;
  1271.     XtSetValues(shellWidget, args, i);
  1272.     
  1273.     /*
  1274.      * Create a cursor for the board widget.
  1275.      */
  1276.     window_attributes.cursor = XCreateFontCursor(xDisplay, XC_hand2);
  1277.     XChangeWindowAttributes(xDisplay, xBoardWindow,
  1278.                 CWCursor, &window_attributes);
  1279.     
  1280.     /*
  1281.      * Inhibit shell resizing.
  1282.      */
  1283.     shellArgs[0].value = (XtArgVal) &w;
  1284.     shellArgs[1].value = (XtArgVal) &h;
  1285.     XtGetValues(shellWidget, shellArgs, 2);
  1286.     shellArgs[4].value = shellArgs[2].value = w;
  1287.     shellArgs[5].value = shellArgs[3].value = h;
  1288.     XtSetValues(shellWidget, &shellArgs[2], 4);
  1289.     
  1290.     CreateGCs();
  1291.     CreateGrid();
  1292.     CreatePieces();
  1293.     CreatePieceMenus();
  1294.     
  1295.     tr = XtParseTranslationTable(globalTranslations);
  1296.     XtAugmentTranslations(formWidget, tr);
  1297.     XtSetArg(args[0], XtNtranslations, &tr);
  1298.     XtGetValues(formWidget, args, 1);
  1299.     XtSetArg(args[0], XtNtranslations, tr);
  1300.     XtSetValues(boardWidget, args, 1);
  1301.     XtAugmentTranslations(boardWidget,
  1302.               XtParseTranslationTable(boardTranslations));
  1303.     XtAugmentTranslations(whiteTimerWidget,
  1304.               XtParseTranslationTable(whiteTranslations));
  1305.     XtAugmentTranslations(blackTimerWidget,
  1306.               XtParseTranslationTable(blackTranslations));
  1307.     
  1308.     XtAddEventHandler(boardWidget, ExposureMask | ButtonPressMask
  1309.               | ButtonReleaseMask | Button1MotionMask | KeyPressMask,
  1310.               False, (XtEventHandler) EventProc, NULL);
  1311.     
  1312.     InitBackEnd2();
  1313.     
  1314.     if (errorExitStatus == -1) {
  1315.     if (appData.icsActive) {
  1316.         ICSInitScript();
  1317.     }
  1318.  
  1319.     signal(SIGINT, IntSigHandler);
  1320.     signal(SIGTERM, IntSigHandler);
  1321.     if (*appData.cmailGameName != NULLCHAR) {
  1322.         signal(SIGUSR1, CmailSigHandler);
  1323.     }
  1324.     }
  1325.  
  1326.     XtAppMainLoop(appContext);
  1327. }
  1328.  
  1329. RETSIGTYPE
  1330. IntSigHandler(sig)
  1331.      int sig;
  1332. {
  1333.     ExitEvent(sig);
  1334. }
  1335.  
  1336. RETSIGTYPE
  1337. CmailSigHandler(sig)
  1338.      int sig;
  1339. {
  1340.     int dummy = 0;
  1341.     int error;
  1342.  
  1343.     signal(SIGUSR1, SIG_IGN);              /* suspend handler     */
  1344.  
  1345.     /* Activate call-back function CmailSigHandlerCallBack()             */
  1346.     OutputToProcess(cmailPR, (char *)(&dummy), sizeof(int), &error);
  1347.  
  1348.     signal(SIGUSR1, CmailSigHandler);          /* re-activate handler */
  1349. }
  1350.  
  1351. void CmailSigHandlerCallBack(isr, message, count, error)
  1352.      InputSourceRef isr;
  1353.      char *message;
  1354.      int count;
  1355.      int error;
  1356. {
  1357.     XtMapWidget(shellWidget);                       /* Open if iconified */
  1358.     XtPopup(shellWidget, XtGrabNone);               /* Raise if lowered  */
  1359.  
  1360.     ReloadCmailMsgEvent(TRUE);                /* Reload cmail msg  */
  1361.  
  1362. }
  1363. /**** end signal code ****/
  1364.  
  1365. void Usage()
  1366. {
  1367.     fprintf(stderr, "Usage: %s\n", programName);
  1368.     fprintf(stderr, "\t-timeControl (or -tc) minutes[:seconds]\n");
  1369.     fprintf(stderr, "\t-movesPerSession (or -mps) number\n");
  1370.     fprintf(stderr, "\t-clockMode (True | False), or -[x]clock\n");
  1371.     fprintf(stderr, "\t-searchTime (or -st) minutes[:seconds]\n");
  1372.     fprintf(stderr, "\t-searchDepth (or -sd) number\n");
  1373.     fprintf(stderr, "\t-matchMode (True | False), or -[x]mm\n");
  1374.     fprintf(stderr, "\t-internetChessServerMode (True | False), or -[x]ics\n");
  1375.     fprintf(stderr, "\t-internetChessServerHost (or -icshost) host_name\n");
  1376.     fprintf(stderr, "\t-loadGameFile (or -lgf) file_name\n");
  1377.     fprintf(stderr, "\t-loadGameIndex (or -lgi) number\n");
  1378.     fprintf(stderr, "\t-boardSize (or -size) (Large | Medium | Small)\n");
  1379.     fprintf(stderr, "\t-noChessProgram (True | False), or -[x]ncp\n");
  1380.     fprintf(stderr, "\t-debugMode (True | False), or -[x]debug\n");
  1381.     fprintf(stderr, "See the man page for more options and information\n");
  1382.     exit(2);
  1383. }
  1384.  
  1385. void ICSInitScript()
  1386. {
  1387.     FILE *f;
  1388.     char buf[MSG_SIZ];
  1389.     char *p;
  1390.  
  1391.     f = fopen(appData.icsLogon, "r");
  1392.     if (f == NULL) {
  1393.     p = getenv("HOME");
  1394.     if (p != NULL) {
  1395.         strcpy(buf, p);
  1396.         strcat(buf, "/");
  1397.         strcat(buf, appData.icsLogon);
  1398.         f = fopen(buf, "r");
  1399.     }
  1400.     }
  1401.     if (f != NULL)
  1402.       ProcessICSInitScript(f);
  1403. }
  1404.  
  1405. void ResetFrontEnd()
  1406. {
  1407.     CommentPopDown();
  1408.     EditCommentPopDown();
  1409.     TagsPopDown();
  1410.     return;
  1411. }
  1412.  
  1413. typedef struct {
  1414.     char *name;
  1415.     Boolean value;
  1416. } Sensitivity;
  1417.  
  1418. void SetMenuSensitivity(sens)
  1419.      Sensitivity *sens;
  1420. {
  1421.     while (sens->name != NULL) {
  1422.     XtSetSensitive(XtNameToWidget(menuBarWidget, sens->name), sens->value);
  1423.     sens++;
  1424.     }
  1425. }
  1426.  
  1427. Sensitivity icsSensitivity[] = {
  1428.     { "menuFile.Mail Move", False },
  1429.     { "menuFile.Reload CMail Message", False },
  1430.     { "menuMode.Machine Black", False },
  1431.     { "menuMode.Machine White", False },
  1432.     { "menuMode.Two Machines", False },
  1433. #ifndef ZIPPY
  1434.     { "menuHelp.Hint", False },
  1435.     { "menuHelp.Book", False },
  1436.     { "menuStep.Move Now", False },
  1437.     { "menuOptions.Show Thinking", False },
  1438. #endif
  1439.     { NULL, False }
  1440. };
  1441.  
  1442. void SetICSMode()
  1443. {
  1444.     SetMenuSensitivity(icsSensitivity);
  1445. }
  1446.  
  1447. Sensitivity ncpSensitivity[] = {    
  1448.     { "menuFile.Mail Move", False },
  1449.     { "menuFile.Reload CMail Message", False },
  1450.     { "menuMode.Machine White", False },
  1451.     { "menuMode.Machine Black", False },
  1452.     { "menuMode.Two Machines", False },
  1453.     { "menuMode.ICS Client", False },
  1454.     { "Action", False },
  1455.     { "menuStep.Revert", False },
  1456.     { "menuStep.Move Now", False },
  1457.     { "menuStep.Retract Move", False },
  1458.     { "menuOptions.Auto Comment", False },
  1459.     { "menuOptions.Auto Flag", False },
  1460.     { "menuOptions.Auto Observe", False },
  1461.     { "menuOptions.Bell", False },
  1462.     { "menuOptions.Quiet Play", False },
  1463.     { "menuOptions.Show Thinking", False },
  1464.     { "menuHelp.Hint", False },
  1465.     { "menuHelp.Book", False },
  1466.     { NULL, False }
  1467. };
  1468.  
  1469. void SetNCPMode()
  1470. {
  1471.     SetMenuSensitivity(ncpSensitivity);
  1472. }
  1473.  
  1474. Sensitivity gnuSensitivity[] = {    
  1475.     { "menuMode.ICS Client", False },
  1476.     { "menuAction.Accept", False },
  1477.     { "menuAction.Decline", False },
  1478.     { "menuAction.Draw", False },
  1479.     { "menuAction.Adjourn", False },
  1480.     { "menuAction.Stop Examining", False },
  1481.     { "menuAction.Stop Observing", False },
  1482.     { "menuStep.Revert", False },
  1483.     { "menuOptions.Auto Comment", False },
  1484.     { "menuOptions.Auto Flag", False },
  1485.     { "menuOptions.Auto Observe", False },
  1486.     { "menuOptions.Quiet Play", False },
  1487.  
  1488.     /* The next two options rely on SetCmailMode being called *after*    */
  1489.     /* SetGNUMode so that when GNU is being used to give hints these     */
  1490.     /* menu options are still available                                  */
  1491.  
  1492.     { "menuFile.Mail Move", False },
  1493.     { "menuFile.Reload CMail Message", False },
  1494.     { NULL, False }
  1495. };
  1496.  
  1497. void SetGNUMode()
  1498. {
  1499.     SetMenuSensitivity(gnuSensitivity);
  1500. }
  1501.  
  1502. Sensitivity cmailSensitivity[] = {    
  1503.     { "Action", True },
  1504.     { "menuAction.Call Flag", False },
  1505.     { "menuAction.Draw", True },
  1506.     { "menuAction.Adjourn", False },
  1507.     { "menuAction.Abort", False },
  1508.     { "menuAction.Stop Observing", False },
  1509.     { "menuAction.Stop Examining", False },
  1510.     { "menuFile.Mail Move", True },
  1511.     { "menuFile.Reload CMail Message", True },
  1512.     { NULL, False }
  1513. };
  1514.  
  1515. void SetCmailMode()
  1516. {
  1517.     SetMenuSensitivity(cmailSensitivity);
  1518. }
  1519.  
  1520. #define Abs(n) ((n)<0 ? -(n) : (n))
  1521.  
  1522. /*
  1523.  * Find a font that matches "pattern" that is as close as
  1524.  * possible to the targetPxlSize.  Prefer fonts that are k
  1525.  * pixels smaller to fonts that are k pixels larger.  The
  1526.  * pattern must be in the X Consortium standard format, 
  1527.  * e.g. "-*-helvetica-bold-r-normal--*-*-*-*-*-*-*-*".
  1528.  * The return value should be freed with XtFree when no
  1529.  * longer needed.
  1530.  */
  1531. char *FindFont(pattern, targetPxlSize)
  1532.      char *pattern;
  1533.      int targetPxlSize;
  1534. {
  1535.     char **fonts, *p, *best;
  1536.     int i, j, nfonts, minerr, err, pxlSize;
  1537.     char errbuf[MSG_SIZ];
  1538.  
  1539.     fonts = XListFonts(xDisplay, pattern, 999999, &nfonts);
  1540.     if (nfonts < 1) {
  1541.     sprintf(errbuf, "No fonts match pattern %s\n", pattern);
  1542.     DisplayFatalError(errbuf, 0, 2);
  1543.     }
  1544.     best = "";
  1545.     minerr = 999999;
  1546.     for (i=0; i<nfonts; i++) {
  1547.     j = 0;
  1548.     p = fonts[i];
  1549.     if (*p != '-') continue;
  1550.     while (j < 7) {
  1551.         if (*p == NULLCHAR) break;
  1552.         if (*p++ == '-') j++;
  1553.     }
  1554.     if (j < 7) continue;
  1555.     pxlSize = atoi(p);
  1556.     if (pxlSize == targetPxlSize) {
  1557.         best = fonts[i];
  1558.         break;
  1559.     }
  1560.     err = pxlSize - targetPxlSize;
  1561.     if (Abs(err) < Abs(minerr) ||
  1562.         (minerr > 0 && err < 0 && -err == minerr)) {
  1563.         best = fonts[i];
  1564.         minerr = err;
  1565.     }
  1566.     }
  1567.     p = (char *) XtMalloc(strlen(best) + 1);
  1568.     strcpy(p, best);
  1569.     XFreeFontNames(fonts);
  1570.     return p;
  1571. }
  1572.  
  1573. void CreateGCs()
  1574. {
  1575.     XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
  1576.       | GCBackground | GCFunction | GCPlaneMask;
  1577.     XGCValues gc_values;
  1578.     GC copyInvertedGC;
  1579.     
  1580.     gc_values.plane_mask = AllPlanes;
  1581.     gc_values.line_width = lineGap;
  1582.     gc_values.line_style = LineSolid;
  1583.     gc_values.function = GXcopy;
  1584.     
  1585.     gc_values.foreground = XBlackPixel(xDisplay, xScreen);
  1586.     gc_values.background = XBlackPixel(xDisplay, xScreen);
  1587.     lineGC = XtGetGC(shellWidget, value_mask, &gc_values);
  1588.     
  1589.     gc_values.background = XWhitePixel(xDisplay, xScreen);
  1590.     coordGC = XtGetGC(shellWidget, value_mask, &gc_values);
  1591.     XSetFont(xDisplay, coordGC, coordFontID);
  1592.     
  1593.     if (appData.monoMode) {
  1594.     gc_values.foreground = XWhitePixel(xDisplay, xScreen);
  1595.     gc_values.background = XBlackPixel(xDisplay, xScreen);
  1596.     lightSquareGC = wbPieceGC 
  1597.       = XtGetGC(shellWidget, value_mask, &gc_values);
  1598.  
  1599.     gc_values.foreground = XBlackPixel(xDisplay, xScreen);
  1600.     gc_values.background = XWhitePixel(xDisplay, xScreen);
  1601.     darkSquareGC = bwPieceGC
  1602.       = XtGetGC(shellWidget, value_mask, &gc_values);
  1603.  
  1604.     if (DefaultDepth(xDisplay, xScreen) == 1) {
  1605.         /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
  1606.         gc_values.function = GXcopyInverted;
  1607.         copyInvertedGC = XtGetGC(shellWidget, value_mask, &gc_values);
  1608.         gc_values.function = GXcopy;
  1609.         if (XBlackPixel(xDisplay, xScreen) == 1) {
  1610.         bwPieceGC = darkSquareGC;
  1611.         wbPieceGC = copyInvertedGC;
  1612.         } else {
  1613.         bwPieceGC = copyInvertedGC;
  1614.         wbPieceGC = lightSquareGC;
  1615.         }
  1616.     }
  1617.     } else {
  1618.     gc_values.foreground = lightSquareColor;
  1619.     gc_values.background = darkSquareColor;
  1620.     lightSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
  1621.     
  1622.     gc_values.foreground = darkSquareColor;
  1623.     gc_values.background = lightSquareColor;
  1624.     darkSquareGC = XtGetGC(shellWidget, value_mask, &gc_values);
  1625.     
  1626.     gc_values.foreground = whitePieceColor;
  1627.     gc_values.background = darkSquareColor;
  1628.     wdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
  1629.     
  1630.     gc_values.foreground = whitePieceColor;
  1631.     gc_values.background = lightSquareColor;
  1632.     wlPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
  1633.     
  1634.     gc_values.foreground = blackPieceColor;
  1635.     gc_values.background = darkSquareColor;
  1636.     bdPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
  1637.     
  1638.     gc_values.foreground = blackPieceColor;
  1639.     gc_values.background = lightSquareColor;
  1640.     blPieceGC = XtGetGC(shellWidget, value_mask, &gc_values);
  1641.     }
  1642. }
  1643.  
  1644. void CreatePieces()
  1645. {
  1646.     u_int ss = squareSize;
  1647.     XSynchronize(xDisplay, True); /* Work-around for xlib/xt
  1648.                      buffering bug */
  1649.     
  1650.     switch (boardSize) {
  1651.       case Small:
  1652.     ReadBitmap(&solidPawnBitmap,   "p40s.bm", p40s_bits, ss, ss);
  1653.     ReadBitmap(&solidKnightBitmap, "n40s.bm", n40s_bits, ss, ss);
  1654.     ReadBitmap(&solidBishopBitmap, "b40s.bm", b40s_bits, ss, ss);
  1655.     ReadBitmap(&solidRookBitmap,   "r40s.bm", r40s_bits, ss, ss);
  1656.     ReadBitmap(&solidQueenBitmap,  "q40s.bm", q40s_bits, ss, ss);
  1657.     ReadBitmap(&solidKingBitmap,   "k40s.bm", k40s_bits, ss, ss);
  1658.         break;
  1659.       case Medium:
  1660.     ReadBitmap(&solidPawnBitmap,   "p64s.bm", p64s_bits, ss, ss);
  1661.     ReadBitmap(&solidKnightBitmap, "n64s.bm", n64s_bits, ss, ss);
  1662.     ReadBitmap(&solidBishopBitmap, "b64s.bm", b64s_bits, ss, ss);
  1663.     ReadBitmap(&solidRookBitmap,   "r64s.bm", r64s_bits, ss, ss);
  1664.     ReadBitmap(&solidQueenBitmap,  "q64s.bm", q64s_bits, ss, ss);
  1665.     ReadBitmap(&solidKingBitmap,   "k64s.bm", k64s_bits, ss, ss);
  1666.         break;
  1667.       case Large:
  1668.     ReadBitmap(&solidPawnBitmap,   "p80s.bm", p80s_bits, ss, ss);
  1669.     ReadBitmap(&solidKnightBitmap, "n80s.bm", n80s_bits, ss, ss);
  1670.     ReadBitmap(&solidBishopBitmap, "b80s.bm", b80s_bits, ss, ss);
  1671.     ReadBitmap(&solidRookBitmap,   "r80s.bm", r80s_bits, ss, ss);
  1672.     ReadBitmap(&solidQueenBitmap,  "q80s.bm", q80s_bits, ss, ss);
  1673.     ReadBitmap(&solidKingBitmap,   "k80s.bm", k80s_bits, ss, ss);
  1674.         break;
  1675.     }
  1676.     
  1677.     if (appData.monoMode) {
  1678.     switch (boardSize) {
  1679.       case Small:
  1680.         ReadBitmap(&outlinePawnBitmap,   "p40o.bm", p40o_bits, ss, ss);
  1681.         ReadBitmap(&outlineKnightBitmap, "n40o.bm", n40o_bits, ss, ss);
  1682.         ReadBitmap(&outlineBishopBitmap, "b40o.bm", b40o_bits, ss, ss);
  1683.         ReadBitmap(&outlineRookBitmap,   "r40o.bm", r40o_bits, ss, ss);
  1684.         ReadBitmap(&outlineQueenBitmap,  "q40o.bm", q40o_bits, ss, ss);
  1685.         ReadBitmap(&outlineKingBitmap,   "k40o.bm", k40o_bits, ss, ss);
  1686.         break;
  1687.       case Medium:
  1688.         ReadBitmap(&outlinePawnBitmap,   "p64o.bm", p64o_bits, ss, ss);
  1689.         ReadBitmap(&outlineKnightBitmap, "n64o.bm", n64o_bits, ss, ss);
  1690.         ReadBitmap(&outlineBishopBitmap, "b64o.bm", b64o_bits, ss, ss);
  1691.         ReadBitmap(&outlineRookBitmap,   "r64o.bm", r64o_bits, ss, ss);
  1692.         ReadBitmap(&outlineQueenBitmap,  "q64o.bm", q64o_bits, ss, ss);
  1693.         ReadBitmap(&outlineKingBitmap,   "k64o.bm", k64o_bits, ss, ss);
  1694.         break;
  1695.       case Large:
  1696.         ReadBitmap(&outlinePawnBitmap,   "p80o.bm", p80o_bits, ss, ss);
  1697.         ReadBitmap(&outlineKnightBitmap, "n80o.bm", n80o_bits, ss, ss);
  1698.         ReadBitmap(&outlineBishopBitmap, "b80o.bm", b80o_bits, ss, ss);
  1699.         ReadBitmap(&outlineRookBitmap,   "r80o.bm", r80o_bits, ss, ss);
  1700.         ReadBitmap(&outlineQueenBitmap,  "q80o.bm", q80o_bits, ss, ss);
  1701.         ReadBitmap(&outlineKingBitmap,   "k80o.bm", k80o_bits, ss, ss);
  1702.         break;
  1703.     }
  1704.     }
  1705.     
  1706.     XSynchronize(xDisplay, False); /* Work-around for xlib/xt
  1707.                       buffering bug */
  1708. }
  1709.  
  1710. void ReadBitmap(pm, name, bits, wreq, hreq)
  1711.      Pixmap *pm;
  1712.      String name;
  1713.      unsigned char bits[];
  1714.      u_int wreq, hreq;
  1715. {
  1716.     int x_hot, y_hot;
  1717.     u_int w, h;
  1718.     int errcode;
  1719.     char msg[MSG_SIZ], fullname[MSG_SIZ];
  1720.     
  1721.     if (*appData.bitmapDirectory == NULLCHAR) {
  1722.     *pm = XCreateBitmapFromData(xDisplay, xBoardWindow, (char *) bits,
  1723.                     wreq, hreq);
  1724.     } else {
  1725.         strcpy(fullname, appData.bitmapDirectory);
  1726.     strcat(fullname, "/");
  1727.     strcat(fullname, name);
  1728.     errcode = XReadBitmapFile(xDisplay, xBoardWindow, fullname,
  1729.                   &w, &h, pm, &x_hot, &y_hot);
  1730.     if (errcode != BitmapSuccess) {
  1731.         switch (errcode) {
  1732.           case BitmapOpenFailed:
  1733.         sprintf(msg, "Can't open bitmap file %s", fullname);
  1734.         break;
  1735.           case BitmapFileInvalid:
  1736.         sprintf(msg, "Invalid bitmap in file %s", fullname);
  1737.         break;
  1738.           case BitmapNoMemory:
  1739.         sprintf(msg, "Ran out of memory reading bitmap file %s",
  1740.             fullname);
  1741.         break;
  1742.           default:
  1743.         sprintf(msg, "Unknown XReadBitmapFile error %d on file %s",
  1744.             errcode, fullname);
  1745.         break;
  1746.         }
  1747.         DisplayFatalError(msg, 0, 1);
  1748.     }
  1749.     if (w != wreq || h != hreq) {
  1750.         sprintf(msg, "Bitmap is %dx%d, should be %dx%d; file %s",
  1751.             w, h, wreq, hreq, fullname);
  1752.         DisplayFatalError(msg, 0, 1);
  1753.     }
  1754.     }
  1755. }
  1756.  
  1757. void CreateGrid()
  1758. {
  1759.     int i;
  1760.     
  1761.     for (i = 0; i < BOARD_SIZE + 1; i++) {
  1762.     gridSegments[i].x1 = gridSegments[i + BOARD_SIZE + 1].y1 = 0;
  1763.     gridSegments[i].y1 = gridSegments[i].y2
  1764.       = lineGap / 2 + (i * (squareSize + lineGap));
  1765.     gridSegments[i].x2 = lineGap + BOARD_SIZE *
  1766.       (squareSize + lineGap);
  1767.     gridSegments[i + BOARD_SIZE + 1].x1 =
  1768.       gridSegments[i + BOARD_SIZE + 1].x2 = lineGap / 2
  1769.         + (i * (squareSize + lineGap));
  1770.     gridSegments[i + BOARD_SIZE + 1].y2 =
  1771.       BOARD_SIZE * (squareSize + lineGap);
  1772.     }
  1773. }
  1774.  
  1775. static void MenuBarSelect(w, addr, index)
  1776.      Widget w;
  1777.      caddr_t addr;
  1778.      caddr_t index;
  1779. {
  1780.     XtActionProc proc = (XtActionProc) addr;
  1781.  
  1782.     (proc)(NULL, NULL, NULL, NULL);
  1783. }
  1784.  
  1785. void CreateMenuBarPopup(parent, name, mb)
  1786.      Widget parent;
  1787.      String name;
  1788.      Menu *mb;
  1789. {
  1790.     int j;
  1791.     Widget menu, entry;
  1792.     MenuItem *mi;
  1793.     Arg args[16];
  1794.  
  1795.     menu = XtCreatePopupShell(name, simpleMenuWidgetClass,
  1796.                   parent, NULL, 0);
  1797.     j = 0;
  1798.     XtSetArg(args[j], XtNleftMargin, 20);   j++;
  1799.     XtSetArg(args[j], XtNrightMargin, 20);  j++;
  1800.     mi = mb->mi;
  1801.     while (mi->string != NULL) {
  1802.     if (strcmp(mi->string, "----") == 0) {
  1803.         entry = XtCreateManagedWidget(mi->string, smeLineObjectClass,
  1804.                       menu, args, j);
  1805.     } else {
  1806.         entry = XtCreateManagedWidget(mi->string, smeBSBObjectClass,
  1807.                       menu, args, j);
  1808.         XtAddCallback(entry, XtNcallback,
  1809.               (XtCallbackProc) MenuBarSelect,
  1810.               (caddr_t) mi->proc);
  1811.     }
  1812.     mi++;
  1813.     }
  1814. }    
  1815.  
  1816. Widget CreateMenuBar(mb)
  1817.      Menu *mb;
  1818. {
  1819.     int j;
  1820.     Widget anchor, menuBar;
  1821.     Arg args[16];
  1822.     char menuName[MSG_SIZ];
  1823.  
  1824.     j = 0;
  1825.     XtSetArg(args[j], XtNorientation, XtorientHorizontal);  j++;
  1826.     XtSetArg(args[j], XtNvSpace, 0);                        j++;
  1827.     XtSetArg(args[j], XtNborderWidth, 0);                   j++;
  1828.     menuBar = XtCreateWidget("menuBar", boxWidgetClass,
  1829.                  formWidget, args, j);
  1830.  
  1831.     while (mb->name != NULL) {
  1832.     strcpy(menuName, "menu");
  1833.     strcat(menuName, mb->name);
  1834.     j = 0;
  1835.     XtSetArg(args[j], XtNmenuName, XtNewString(menuName));  j++;
  1836.     XtSetArg(args[j], XtNborderWidth, 0);                   j++;
  1837.     anchor = XtCreateManagedWidget(mb->name, menuButtonWidgetClass,
  1838.                        menuBar, args, j);
  1839.     CreateMenuBarPopup(menuBar, menuName, mb);
  1840.     mb++;
  1841.     }
  1842.     return menuBar;
  1843. }
  1844.  
  1845. Widget CreateButtonBar(mi)
  1846.      MenuItem *mi;
  1847. {
  1848.     int j;
  1849.     Widget button, buttonBar;
  1850.     Arg args[16];
  1851.  
  1852.     j = 0;
  1853.     XtSetArg(args[j], XtNorientation, XtorientHorizontal);  j++;
  1854.     XtSetArg(args[j], XtNvSpace, 0);                        j++;
  1855.     XtSetArg(args[j], XtNborderWidth, 0);                   j++;
  1856.     buttonBar = XtCreateWidget("buttonBar", boxWidgetClass,
  1857.                    formWidget, args, j);
  1858.  
  1859.     while (mi->string != NULL) {
  1860.     j = 0;
  1861.     button = XtCreateManagedWidget(mi->string, commandWidgetClass,
  1862.                        buttonBar, args, j);
  1863.     XtAddCallback(button, XtNcallback,
  1864.               (XtCallbackProc) MenuBarSelect,
  1865.               (caddr_t) mi->proc);
  1866.     mi++;
  1867.     }
  1868.     return buttonBar;
  1869. }     
  1870.  
  1871. void CreatePieceMenus()
  1872. {
  1873.     int i;
  1874.     Widget entry;
  1875.     Arg args[16];
  1876.     ChessSquare selection;
  1877.     
  1878.     XtSetArg(args[0], XtNlabel, "White");
  1879.     whitePieceMenu = XtCreatePopupShell("menuW", simpleMenuWidgetClass,
  1880.                     boardWidget, args, 1);
  1881.     for (i = 0; i < PIECE_MENU_SIZE; i++) {
  1882.     String item = pieceMenuStrings[i];
  1883.     
  1884.     if (strcmp(item, "----") == 0) {
  1885.         entry = XtCreateManagedWidget(item, smeLineObjectClass,
  1886.                       whitePieceMenu, NULL, 0);
  1887.     } else {
  1888.         entry = XtCreateManagedWidget(item, smeBSBObjectClass,
  1889.                       whitePieceMenu, NULL, 0);
  1890.         selection = pieceMenuTranslation[0][i];
  1891.         XtAddCallback(entry, XtNcallback,
  1892.               (XtCallbackProc) PieceMenuSelect,
  1893.               (caddr_t) selection);
  1894.         if (selection == WhitePawn) {
  1895.         XtSetArg(args[0], XtNpopupOnEntry, entry);
  1896.         XtSetValues(whitePieceMenu, args, 1);
  1897.         }
  1898.     }
  1899.     }
  1900.     
  1901.     XtSetArg(args[0], XtNlabel, "Black");
  1902.     blackPieceMenu = XtCreatePopupShell("menuB", simpleMenuWidgetClass,
  1903.                     boardWidget, args, 1);
  1904.     for (i = 0; i < PIECE_MENU_SIZE; i++) {
  1905.     String item = pieceMenuStrings[i];
  1906.     
  1907.     if (strcmp(item, "----") == 0) {
  1908.         entry = XtCreateManagedWidget(item, smeLineObjectClass,
  1909.                       blackPieceMenu, NULL, 0);
  1910.     } else {
  1911.         entry = XtCreateManagedWidget(item, smeBSBObjectClass,
  1912.                       blackPieceMenu, NULL, 0);
  1913.         selection = pieceMenuTranslation[1][i];
  1914.         XtAddCallback(entry, XtNcallback,
  1915.               (XtCallbackProc) PieceMenuSelect,
  1916.               (caddr_t) selection);
  1917.         if (selection == BlackPawn) {
  1918.         XtSetArg(args[0], XtNpopupOnEntry, entry);
  1919.         XtSetValues(blackPieceMenu, args, 1);
  1920.         }
  1921.     }
  1922.     }
  1923.     
  1924.     XtRegisterGrabAction(PieceMenuPopup, True,
  1925.              (unsigned)(ButtonPressMask|ButtonReleaseMask),
  1926.              GrabModeAsync, GrabModeAsync);
  1927. }    
  1928.  
  1929. void PieceMenuPopup(w, event, params, num_params)
  1930.      Widget w;
  1931.      XEvent *event;
  1932.      String *params;
  1933.      Cardinal *num_params;
  1934. {
  1935.     if (event->type != ButtonPress) return;
  1936.     if (gameMode != EditPosition && gameMode != IcsExamining) return;
  1937.     
  1938.     if (((pmFromX = EventToSquare(event->xbutton.x)) < 0) ||
  1939.     ((pmFromY = EventToSquare(event->xbutton.y)) < 0)) {
  1940.     pmFromX = pmFromY = -1;
  1941.     return;
  1942.     }
  1943.     if (flipView)
  1944.       pmFromX = BOARD_SIZE - 1 - pmFromX;
  1945.     else
  1946.       pmFromY = BOARD_SIZE - 1 - pmFromY;
  1947.     
  1948.     XtPopupSpringLoaded(XtNameToWidget(boardWidget, params[0]));
  1949. }
  1950.  
  1951. static void PieceMenuSelect(w, piece, junk)
  1952.      Widget w;
  1953.      ChessSquare piece;
  1954.      caddr_t junk;
  1955. {
  1956.     if (pmFromX < 0 || pmFromY < 0) return;
  1957.     EditPositionMenuEvent(piece, pmFromX, pmFromY);
  1958. }
  1959.  
  1960. void WhiteClock(w, event, prms, nprms)
  1961.      Widget w;
  1962.      XEvent *event;
  1963.      String *prms;
  1964.      Cardinal *nprms;
  1965. {
  1966.     if (gameMode == EditPosition) {
  1967.     SetWhiteToPlayEvent();
  1968.     } else if (gameMode == IcsPlayingBlack || gameMode == MachinePlaysWhite) {
  1969.     CallFlagEvent();
  1970.     }
  1971. }
  1972.  
  1973. void BlackClock(w, event, prms, nprms)
  1974.      Widget w;
  1975.      XEvent *event;
  1976.      String *prms;
  1977.      Cardinal *nprms;
  1978. {
  1979.     if (gameMode == EditPosition) {
  1980.     SetBlackToPlayEvent();
  1981.     } else if (gameMode == IcsPlayingWhite || gameMode == MachinePlaysBlack) {
  1982.     CallFlagEvent();
  1983.     }
  1984. }
  1985.  
  1986.  
  1987. /*
  1988.  * If the user selects on a border boundary, return -1; if off the board,
  1989.  *   return -2.  Otherwise map the event coordinate to the square.
  1990.  */
  1991. int EventToSquare(x)
  1992.      int x;
  1993. {
  1994.     if (x <= 0) 
  1995.       return -2;
  1996.     if (x < lineGap)
  1997.       return -1;
  1998.     x -= lineGap;
  1999.     if ((x % (squareSize + lineGap)) >= squareSize)
  2000.       return -1;
  2001.     x /= (squareSize + lineGap);
  2002.     if (x >= BOARD_SIZE)
  2003.       return -2;
  2004.     return x;
  2005. }
  2006.  
  2007. void DrawSquare(row, column, piece)
  2008.      int row, column;
  2009.      ChessSquare piece;
  2010. {
  2011.     int square_color, x, y, direction, font_ascent, font_descent;
  2012.     char string[2];
  2013.     XCharStruct overall;
  2014.     
  2015.     if (flipView) {
  2016.     x = lineGap + ((BOARD_SIZE-1)-column) * 
  2017.       (squareSize + lineGap);
  2018.     y = lineGap + row * (squareSize + lineGap);
  2019.     } else {
  2020.     x = lineGap + column * (squareSize + lineGap);
  2021.     y = lineGap + ((BOARD_SIZE-1)-row) * 
  2022.       (squareSize + lineGap);
  2023.     }
  2024.     
  2025.     square_color = ((column + row) % 2) == 1;
  2026.     
  2027.     if (piece == EmptySquare) {
  2028.     XFillRectangle(xDisplay, xBoardWindow,
  2029.                square_color ? lightSquareGC : darkSquareGC,
  2030.                x, y, squareSize, squareSize);
  2031.     } else if (appData.monoMode) {
  2032.     if (DefaultDepth(xDisplay, xScreen) == 1) {
  2033.         /* Avoid XCopyPlane on 1-bit screens to work around Sun bug */
  2034.         if (square_color)
  2035.           XCopyArea(xDisplay, (int) piece < (int) BlackPawn
  2036.              ? *pieceToOutline[(int) piece]
  2037.              : *pieceToSolid[(int) piece],
  2038.              xBoardWindow, bwPieceGC, 0, 0,
  2039.              squareSize, squareSize, x, y);
  2040.         else
  2041.           XCopyArea(xDisplay, (int) piece < (int) BlackPawn
  2042.              ? *pieceToSolid[(int) piece]
  2043.              : *pieceToOutline[(int) piece],
  2044.              xBoardWindow, wbPieceGC, 0, 0,
  2045.              squareSize, squareSize, x, y);
  2046.     } else {
  2047.         if (square_color)
  2048.           XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
  2049.              ? *pieceToOutline[(int) piece]
  2050.              : *pieceToSolid[(int) piece],
  2051.              xBoardWindow, bwPieceGC, 0, 0,
  2052.              squareSize, squareSize, x, y, 1);
  2053.         else
  2054.           XCopyPlane(xDisplay, (int) piece < (int) BlackPawn
  2055.              ? *pieceToSolid[(int) piece]
  2056.              : *pieceToOutline[(int) piece],
  2057.              xBoardWindow, wbPieceGC, 0, 0,
  2058.              squareSize, squareSize, x, y, 1);
  2059.     }
  2060.     } else {
  2061.     if (square_color)
  2062.       XCopyPlane(xDisplay, *pieceToSolid[(int) piece],
  2063.              xBoardWindow, (int) piece < (int) BlackPawn
  2064.              ? wlPieceGC : blPieceGC, 0, 0,
  2065.              squareSize, squareSize, x, y, 1);
  2066.     else
  2067.       XCopyPlane(xDisplay, *pieceToSolid[(int) piece],
  2068.              xBoardWindow, (int) piece < (int) BlackPawn
  2069.              ? wdPieceGC : bdPieceGC, 0, 0,
  2070.              squareSize, squareSize, x, y, 1);
  2071.     }
  2072.     string[1] = NULLCHAR;
  2073.     if (appData.showCoords && row == (flipView ? 7 : 0)) {
  2074.     string[0] = 'a' + column;
  2075.     XTextExtents(coordFontStruct, string, 1, &direction, 
  2076.              &font_ascent, &font_descent, &overall);
  2077.     if (appData.monoMode) {
  2078.         XDrawImageString(xDisplay, xBoardWindow, coordGC,
  2079.                  x + squareSize - overall.width - 2, 
  2080.                  y + squareSize - font_descent - 1, string, 1);
  2081.     } else {
  2082.         XDrawString(xDisplay, xBoardWindow, coordGC,
  2083.             x + squareSize - overall.width - 2, 
  2084.             y + squareSize - font_descent - 1, string, 1);
  2085.     }
  2086.     }
  2087.     if (appData.showCoords && column == (flipView ? 7 : 0)) {
  2088.     string[0] = '1' + row;
  2089.     XTextExtents(coordFontStruct, string, 1, &direction, 
  2090.              &font_ascent, &font_descent, &overall);
  2091.     if (appData.monoMode) {
  2092.         XDrawImageString(xDisplay, xBoardWindow, coordGC,
  2093.                  x + 2, y + font_ascent + 1, string, 1);
  2094.     } else {
  2095.         XDrawString(xDisplay, xBoardWindow, coordGC,
  2096.             x + 2, y + font_ascent + 1, string, 1);
  2097.     }        
  2098.     }   
  2099. }
  2100.  
  2101. void EventProc(widget, unused, event)
  2102.      Widget widget;
  2103.      caddr_t unused;
  2104.      XEvent *event;
  2105. {
  2106.     if (event->type == MappingNotify) {
  2107.     XRefreshKeyboardMapping((XMappingEvent *) event);
  2108.     return;
  2109.     }
  2110.     
  2111.     if (!XtIsRealized(widget))
  2112.       return;
  2113.     
  2114.     if ((event->type == ButtonPress) || (event->type == ButtonRelease))
  2115.       if (event->xbutton.button != Button1)
  2116.     return;
  2117.     
  2118.     switch (event->type) {
  2119.       case Expose:
  2120.     DrawPositionProc(widget, event, NULL, NULL);
  2121.     break;
  2122.       default:
  2123.     return;
  2124.     }
  2125. }
  2126.  
  2127.  
  2128. void DrawPosition(fullRedraw, board)
  2129.      /*Boolean*/int fullRedraw;
  2130.      Board board;
  2131. {
  2132.     XDrawPosition(boardWidget, fullRedraw, board);
  2133. }
  2134.  
  2135. /*
  2136.  * event handler for redrawing the board
  2137.  */
  2138. void XDrawPosition(w, repaint, board)
  2139.      Widget w;
  2140.      /*Boolean*/int repaint;
  2141.      Board board;
  2142. {
  2143.     int i, j;
  2144.     static int lastFlipView = 0;
  2145.     static int lastBoardValid = 0;
  2146.     static Board lastBoard;
  2147.     Arg args[16];
  2148.     
  2149.     if (board == NULL) {
  2150.     if (!lastBoardValid) return;
  2151.     board = lastBoard;
  2152.     }
  2153.  
  2154.     /*
  2155.      * It would be simpler to clear the window with XClearWindow()
  2156.      * but this causes a very distracting flicker.
  2157.      */
  2158.     
  2159.     if (!repaint && lastBoardValid && lastFlipView == flipView) {
  2160.     for (i = 0; i < BOARD_SIZE; i++)
  2161.       for (j = 0; j < BOARD_SIZE; j++)
  2162.         if (board[i][j] != lastBoard[i][j])
  2163.           DrawSquare(i, j, board[i][j]);
  2164.     } else {
  2165.     XDrawSegments(xDisplay, xBoardWindow, lineGC,
  2166.               gridSegments, (BOARD_SIZE + 1) * 2);
  2167.     
  2168.     for (i = 0; i < BOARD_SIZE; i++)
  2169.       for (j = 0; j < BOARD_SIZE; j++)
  2170.         DrawSquare(i, j, board[i][j]);
  2171.     }
  2172.     
  2173.     if (!lastBoardValid || lastFlipView != flipView) {
  2174.     XtSetArg(args[0], XtNleftBitmap, (flipView ? xMarkPixmap : None));
  2175.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Flip View"),
  2176.             args, 1);
  2177.     }
  2178.  
  2179.     CopyBoard(lastBoard, board);
  2180.     lastBoardValid = 1;
  2181.     lastFlipView = flipView;
  2182.     
  2183.     XSync(xDisplay, False);
  2184. }
  2185.  
  2186. /*
  2187.  * event handler for redrawing the board
  2188.  */
  2189. void DrawPositionProc(w, event, prms, nprms)
  2190.      Widget w;
  2191.      XEvent *event;
  2192.      String *prms;
  2193.      Cardinal *nprms;
  2194. {
  2195.     XDrawPosition(w, True, NULL);
  2196. }
  2197.  
  2198.  
  2199. /*
  2200.  * event handler for parsing user moves
  2201.  */
  2202. void HandleUserMove(w, event, prms, nprms)
  2203.      Widget w;
  2204.      XEvent *event;
  2205.      String *prms;
  2206.      Cardinal *nprms;
  2207. {
  2208.     int x, y;
  2209.     
  2210.     if (w != boardWidget)
  2211.       return;
  2212.     
  2213.     if (promotionUp) {
  2214.     XtPopdown(promotionShell);
  2215.     XtDestroyWidget(promotionShell);
  2216.     promotionUp = False;
  2217.     fromX = fromY = -1;
  2218.     }
  2219.     
  2220.     x = EventToSquare(event->xbutton.x);
  2221.     y = EventToSquare(event->xbutton.y);
  2222.     if (!flipView && y >= 0) {
  2223.     y = BOARD_SIZE - 1 - y;
  2224.     }
  2225.     if (flipView && x >= 0) {
  2226.     x = BOARD_SIZE - 1 - x;
  2227.     }
  2228.  
  2229.     switch (event->type) {
  2230.       case ButtonPress:
  2231.     if (errorExitStatus != -1) return;
  2232.     if (errorUp) ErrorPopDown();
  2233.     if (OKToStartUserMove(x, y)) {
  2234.         fromX = x;
  2235.         fromY = y;
  2236.     } else {
  2237.         fromX = fromY = -1;
  2238.     }
  2239.     break;
  2240.  
  2241.       case ButtonRelease:
  2242.     toX = x;
  2243.     toY = y;
  2244.     if (IsPromotion(fromX, fromY, toX, toY)) {
  2245.         if (appData.alwaysPromoteToQueen) {
  2246.         UserMoveEvent(fromX, fromY, toX, toY, 'q');
  2247.         fromX = fromY = -1;
  2248.         } else {
  2249.         PromotionPopUp();
  2250.         }
  2251.     } else {
  2252.         UserMoveEvent(fromX, fromY, toX, toY, NULLCHAR);
  2253.         fromX = fromY = -1;
  2254.     }
  2255.     break;
  2256.     }
  2257.  
  2258. }
  2259.  
  2260. Widget CommentCreate(name, text, mutable, callback)
  2261.      char *name, *text;
  2262.      int /*Boolean*/ mutable;
  2263.      XtCallbackProc callback;
  2264. {
  2265.     Arg args[16];
  2266.     Widget shell, form, edit, b_ok, b_cancel, b_clear, b_close, b_edit;
  2267.     Dimension fw_width;
  2268.     int j;
  2269.  
  2270.     j = 0;
  2271.     XtSetArg(args[j], XtNwidth, &fw_width);  j++;
  2272.     XtGetValues(formWidget, args, j);
  2273.  
  2274.     j = 0;
  2275.     XtSetArg(args[j], XtNresizable, True);  j++;
  2276. #if TOPLEVEL
  2277.     shell =
  2278.       XtCreatePopupShell(name, topLevelShellWidgetClass,
  2279.              shellWidget, args, j);
  2280. #else
  2281.     shell =
  2282.       XtCreatePopupShell(name, transientShellWidgetClass,
  2283.              shellWidget, args, j);
  2284. #endif
  2285.     j = 0;
  2286.     form =
  2287.       XtCreateManagedWidget("form", formWidgetClass, shell, args, j);
  2288.  
  2289.     j = 0;
  2290.     if (mutable) {
  2291.     XtSetArg(args[j], XtNeditType, XawtextEdit);  j++;
  2292.     XtSetArg(args[j], XtNuseStringInPlace, False);  j++;
  2293.     }
  2294.     XtSetArg(args[j], XtNstring, text);  j++;
  2295.     XtSetArg(args[j], XtNtop, XtChainTop);  j++;
  2296.     XtSetArg(args[j], XtNbottom, XtChainBottom);  j++;
  2297.     XtSetArg(args[j], XtNleft, XtChainLeft);  j++;
  2298.     XtSetArg(args[j], XtNright, XtChainRight);  j++;
  2299.     XtSetArg(args[j], XtNresizable, True);  j++;
  2300.     XtSetArg(args[j], XtNwidth, fw_width);  j++;  /*force wider than buttons*/
  2301.     XtSetArg(args[j], XtNscrollVertical, XawtextScrollWhenNeeded);  j++;
  2302.     XtSetArg(args[j], XtNautoFill, True);  j++;
  2303.     edit =
  2304.       XtCreateManagedWidget("text", asciiTextWidgetClass, form, args, j);
  2305.  
  2306.     if (mutable) {
  2307.     j = 0;
  2308.     XtSetArg(args[j], XtNfromVert, edit);  j++;
  2309.     XtSetArg(args[j], XtNtop, XtChainBottom); j++;
  2310.     XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
  2311.     XtSetArg(args[j], XtNleft, XtChainLeft); j++;
  2312.     XtSetArg(args[j], XtNright, XtChainLeft); j++;
  2313.     b_ok =
  2314.       XtCreateManagedWidget("ok", commandWidgetClass, form, args, j);
  2315.     XtAddCallback(b_ok, XtNcallback, callback, (XtPointer) 0);
  2316.  
  2317.     j = 0;
  2318.     XtSetArg(args[j], XtNfromVert, edit);  j++;
  2319.     XtSetArg(args[j], XtNfromHoriz, b_ok);  j++;
  2320.     XtSetArg(args[j], XtNtop, XtChainBottom); j++;
  2321.     XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
  2322.     XtSetArg(args[j], XtNleft, XtChainLeft); j++;
  2323.     XtSetArg(args[j], XtNright, XtChainLeft); j++;
  2324.     b_cancel =
  2325.       XtCreateManagedWidget("cancel", commandWidgetClass, form, args, j);
  2326.     XtAddCallback(b_cancel, XtNcallback, callback, (XtPointer) 0);
  2327.  
  2328.     j = 0;
  2329.     XtSetArg(args[j], XtNfromVert, edit);  j++;
  2330.     XtSetArg(args[j], XtNfromHoriz, b_cancel);  j++;
  2331.     XtSetArg(args[j], XtNtop, XtChainBottom); j++;
  2332.     XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
  2333.     XtSetArg(args[j], XtNleft, XtChainLeft); j++;
  2334.     XtSetArg(args[j], XtNright, XtChainLeft); j++;
  2335.     b_clear =
  2336.       XtCreateManagedWidget("clear", commandWidgetClass, form, args, j);
  2337.     XtAddCallback(b_clear, XtNcallback, callback, (XtPointer) 0);
  2338.     } else {
  2339.     j = 0;
  2340.     XtSetArg(args[j], XtNfromVert, edit);  j++;
  2341.     XtSetArg(args[j], XtNtop, XtChainBottom); j++;
  2342.     XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
  2343.     XtSetArg(args[j], XtNleft, XtChainLeft); j++;
  2344.     XtSetArg(args[j], XtNright, XtChainLeft); j++;
  2345.     b_close =
  2346.       XtCreateManagedWidget("close", commandWidgetClass, form, args, j);
  2347.     XtAddCallback(b_close, XtNcallback, callback, (XtPointer) 0);
  2348.  
  2349.     j = 0;
  2350.     XtSetArg(args[j], XtNfromVert, edit);  j++;
  2351.     XtSetArg(args[j], XtNfromHoriz, b_close);  j++;
  2352.     XtSetArg(args[j], XtNtop, XtChainBottom); j++;
  2353.     XtSetArg(args[j], XtNbottom, XtChainBottom); j++;
  2354.     XtSetArg(args[j], XtNleft, XtChainLeft); j++;
  2355.     XtSetArg(args[j], XtNright, XtChainLeft); j++;
  2356.     b_edit =
  2357.       XtCreateManagedWidget("edit", commandWidgetClass, form, args, j);
  2358.     XtAddCallback(b_edit, XtNcallback, callback, (XtPointer) 0);
  2359.     }
  2360.  
  2361.     if (commentX == -1) {
  2362.     Position y1, y2;
  2363.     int xx, yy;
  2364.     Window junk;
  2365.  
  2366.     j = 0;
  2367.     XtSetArg(args[j], XtNy, &y1); j++;
  2368.     XtGetValues(menuBarWidget, args, j);
  2369.     y1 -= appData.borderYoffset; /* offset by banner height */
  2370.     j = 0;
  2371.     XtSetArg(args[j], XtNy, &y2); j++;
  2372.     XtGetValues(messageWidget, args, j);
  2373.     commentW = fw_width - 16;
  2374.     commentH = y2 - y1;
  2375.  
  2376.     XSync(xDisplay, False);
  2377. #ifdef NOTDEF
  2378.     /* This code seems to tickle an X bug if it is executed too soon
  2379.        after xboard starts up.  The coordinates get transformed as if
  2380.        the main window was positioned at (0, 0).
  2381.     */
  2382.     XtTranslateCoords(shellWidget, (fw_width - commentW) / 2, y1,
  2383.               &commentX, &commentY);
  2384. #else /*!NOTDEF*/
  2385.         XTranslateCoordinates(xDisplay, XtWindow(shellWidget),
  2386.                   RootWindowOfScreen(XtScreen(shellWidget)),
  2387.                   (fw_width - commentW) / 2, y1,
  2388.                   &xx, &yy, &junk);
  2389.     commentX = xx;
  2390.     commentY = yy;
  2391. #endif /*!NOTDEF*/
  2392.     }
  2393.     j = 0;
  2394.     XtSetArg(args[j], XtNheight, commentH);  j++;
  2395.     XtSetArg(args[j], XtNwidth, commentW);  j++;
  2396.     XtSetArg(args[j], XtNx, commentX - appData.borderXoffset);  j++;
  2397.     XtSetArg(args[j], XtNy, commentY - appData.borderYoffset);  j++;
  2398.     XtSetValues(shell, args, j);
  2399.  
  2400.     XtRealizeWidget(shell);
  2401.  
  2402.     return shell;
  2403. }
  2404.  
  2405. static int savedIndex;  /* gross that this is global */
  2406.  
  2407. void EditCommentPopUp(index, title, text)
  2408.      int index;
  2409.      char *title, *text;
  2410. {
  2411.     Widget edit;
  2412.     Arg args[16];
  2413.     int j;
  2414.  
  2415.     savedIndex = index;
  2416.     if (text == NULL) text = "";
  2417.  
  2418.     if (editShell == NULL) {
  2419.     editShell =
  2420.       CommentCreate(title, text, True, EditCommentCallback); 
  2421.     } else {
  2422.     edit = XtNameToWidget(editShell, "form.text");
  2423.     j = 0;
  2424.     XtSetArg(args[j], XtNstring, text); j++;
  2425.     XtSetValues(edit, args, j);
  2426.     j = 0;
  2427.     XtSetArg(args[j], XtNiconName, (XtArgVal) title);   j++;
  2428.     XtSetArg(args[j], XtNtitle, (XtArgVal) title);      j++;
  2429.     XtSetValues(editShell, args, j);
  2430.     }
  2431.  
  2432.     XtPopup(editShell, XtGrabNone);
  2433.     XtSetKeyboardFocus(shellWidget, editShell);
  2434.  
  2435.     editUp = True;
  2436.     j = 0;
  2437.     XtSetArg(args[j], XtNleftBitmap, xMarkPixmap); j++;
  2438.     XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),
  2439.         args, j);
  2440. }
  2441.  
  2442. void EditCommentCallback(w, client_data, call_data)
  2443.      Widget w;
  2444.      XtPointer client_data, call_data;
  2445. {
  2446.     String name, val;
  2447.     Arg args[16];
  2448.     int j;
  2449.     Widget edit;
  2450.  
  2451.     j = 0;
  2452.     XtSetArg(args[j], XtNlabel, &name);  j++;
  2453.     XtGetValues(w, args, j);
  2454.  
  2455.     if (strcmp(name, "ok") == 0) {
  2456.     edit = XtNameToWidget(editShell, "form.text");
  2457.     j = 0;
  2458.     XtSetArg(args[j], XtNstring, &val); j++;
  2459.     XtGetValues(edit, args, j);
  2460.     ReplaceComment(savedIndex, val);
  2461.     EditCommentPopDown();
  2462.     } else if (strcmp(name, "cancel") == 0) {
  2463.     EditCommentPopDown();
  2464.     } else if (strcmp(name, "clear") == 0) {
  2465.     edit = XtNameToWidget(editShell, "form.text");
  2466.     XtCallActionProc(edit, "select-all", NULL, NULL, 0);
  2467.     XtCallActionProc(edit, "kill-selection", NULL, NULL, 0);
  2468.     }
  2469. }
  2470.  
  2471. void EditCommentPopDown()
  2472. {
  2473.     Arg args[16];
  2474.     int j;
  2475.  
  2476.     if (!editUp) return;
  2477.     j = 0;
  2478.     XtSetArg(args[j], XtNx, &commentX); j++;
  2479.     XtSetArg(args[j], XtNy, &commentY); j++;
  2480.     XtSetArg(args[j], XtNheight, &commentH); j++;
  2481.     XtSetArg(args[j], XtNwidth, &commentW); j++;
  2482.     XtGetValues(editShell, args, j);
  2483.     XtPopdown(editShell);
  2484.     XtSetKeyboardFocus(shellWidget, formWidget);
  2485.     editUp = False;
  2486.     j = 0;
  2487.     XtSetArg(args[j], XtNleftBitmap, None); j++;
  2488.     XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Edit Comment"),
  2489.         args, j);
  2490. }
  2491.  
  2492. void CommentPopUp(title, text)
  2493.      char *title, *text;
  2494. {
  2495.     Arg args[16];
  2496.     int j;
  2497.     Widget edit;
  2498.  
  2499.     if (commentShell == NULL) {
  2500.     commentShell =
  2501.       CommentCreate(title, text, False, CommentCallback);
  2502.     } else {
  2503.     edit = XtNameToWidget(commentShell, "form.text");
  2504.     j = 0;
  2505.     XtSetArg(args[j], XtNstring, text); j++;
  2506.     XtSetValues(edit, args, j);
  2507.     j = 0;
  2508.     XtSetArg(args[j], XtNiconName, (XtArgVal) title);   j++;
  2509.     XtSetArg(args[j], XtNtitle, (XtArgVal) title);      j++;
  2510.     XtSetValues(commentShell, args, j);
  2511.     }
  2512.  
  2513.     XtPopup(commentShell, XtGrabNone);
  2514.     XSync(xDisplay, False);
  2515.  
  2516.     commentUp = True;
  2517. }
  2518.  
  2519. void CommentCallback(w, client_data, call_data)
  2520.      Widget w;
  2521.      XtPointer client_data, call_data;
  2522. {
  2523.     String name;
  2524.     Arg args[16];
  2525.     int j;
  2526.  
  2527.     j = 0;
  2528.     XtSetArg(args[j], XtNlabel, &name);  j++;
  2529.     XtGetValues(w, args, j);
  2530.  
  2531.     if (strcmp(name, "close") == 0) {
  2532.     CommentPopDown();
  2533.     } else if (strcmp(name, "edit") == 0) {
  2534.     CommentPopDown();
  2535.     EditCommentEvent();
  2536.     }
  2537. }
  2538.  
  2539.  
  2540. void CommentPopDown()
  2541. {
  2542.     Arg args[16];
  2543.     int j;
  2544.  
  2545.     if (!commentUp) return;
  2546.     j = 0;
  2547.     XtSetArg(args[j], XtNx, &commentX); j++;
  2548.     XtSetArg(args[j], XtNy, &commentY); j++;
  2549.     XtSetArg(args[j], XtNwidth, &commentW); j++;
  2550.     XtSetArg(args[j], XtNheight, &commentH); j++;
  2551.     XtGetValues(commentShell, args, j);
  2552.     XtPopdown(commentShell);
  2553.     XSync(xDisplay, False);
  2554.     commentUp = False;
  2555. }
  2556.  
  2557.  
  2558. void FileNamePopUp(label, def, proc, openMode)
  2559.      char *label;
  2560.      char *def;
  2561.      FileProc proc;
  2562.      char *openMode;
  2563. {
  2564.     Arg args[16];
  2565.     Widget popup, dialog;
  2566.     Window root, child;
  2567.     int x, y;
  2568.     int win_x, win_y;
  2569.     unsigned int mask;
  2570.     
  2571.     fileProc = proc;          /* I can't see a way not */
  2572.     fileOpenMode = openMode;  /*   to use globals here */
  2573.     
  2574.     XtSetArg(args[0], XtNresizable, True);
  2575.     XtSetArg(args[1], XtNwidth, DIALOG_SIZE);
  2576.     
  2577.     popup =
  2578.       XtCreatePopupShell("File Name Prompt", transientShellWidgetClass,
  2579.              shellWidget, args, 2);
  2580.     
  2581.     XtSetArg(args[0], XtNlabel, label);
  2582.     XtSetArg(args[1], XtNvalue, def);
  2583.     
  2584.     dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
  2585.                    popup, args, 2);
  2586.     
  2587.     XawDialogAddButton(dialog, "ok", FileNameCallback, (XtPointer) dialog);
  2588.     XawDialogAddButton(dialog, "cancel", FileNameCallback,
  2589.                (XtPointer) dialog);
  2590.     
  2591.     XtRealizeWidget(popup);
  2592.     
  2593.     XQueryPointer(xDisplay, xBoardWindow, &root, &child,
  2594.           &x, &y, &win_x, &win_y, &mask);
  2595.     
  2596.     XtSetArg(args[0], XtNx, x - 10);
  2597.     XtSetArg(args[1], XtNy, y - 10);
  2598.     XtSetValues(popup, args, 2);
  2599.     
  2600.     XtPopup(popup, XtGrabExclusive);
  2601.     filenameUp = True;
  2602.     
  2603.     XtSetKeyboardFocus(shellWidget, popup);
  2604. }
  2605.  
  2606. void FileNameCallback(w, client_data, call_data)
  2607.      Widget w;
  2608.      XtPointer client_data, call_data;
  2609. {
  2610.     String name;
  2611.     Arg args[16];
  2612.     
  2613.     XtSetArg(args[0], XtNlabel, &name);
  2614.     XtGetValues(w, args, 1);
  2615.     
  2616.     if (strcmp(name, "cancel") == 0) {
  2617.     XtPopdown(w = XtParent(XtParent(w)));
  2618.     XtDestroyWidget(w);
  2619.     filenameUp = False;
  2620.     ModeHighlight();
  2621.     return;
  2622.     }
  2623.     
  2624.     FileNameAction(w, NULL, NULL, NULL);
  2625. }
  2626.  
  2627. void FileNameAction(w, event, prms, nprms)
  2628.      Widget w;
  2629.      XEvent *event;
  2630.      String *prms;
  2631.      Cardinal *nprms;
  2632. {
  2633.     char buf[MSG_SIZ];
  2634.     String name;
  2635.     FILE *f;
  2636.     char *p;
  2637.     int index;
  2638.  
  2639.     name = XawDialogGetValueString(w = XtParent(w));
  2640.     
  2641.     if ((name != NULL) && (*name != NULLCHAR)) {
  2642.     strcpy(buf, name);
  2643.     XtPopdown(w = XtParent(w));
  2644.     XtDestroyWidget(w);
  2645.     filenameUp = False;
  2646.  
  2647.     p = strrchr(buf, ' ');
  2648.     if (p == NULL) {
  2649.         index = 0;
  2650.     } else {
  2651.         *p++ = NULLCHAR;
  2652.         index = atoi(p);
  2653.     }
  2654.     f = fopen(buf, fileOpenMode);
  2655.     if (f == NULL) {
  2656.         DisplayError("Failed to open file", errno);
  2657.     } else {
  2658.         (void) (*fileProc)(f, index, buf);
  2659.     }
  2660.     ModeHighlight();
  2661.     XtSetKeyboardFocus(shellWidget, formWidget);
  2662.     return;
  2663.     }
  2664.     
  2665.     XtPopdown(w = XtParent(w));
  2666.     XtDestroyWidget(w);
  2667.     filenameUp = False;
  2668.     ModeHighlight();
  2669.     XtSetKeyboardFocus(shellWidget, formWidget);
  2670. }
  2671.  
  2672. void PromotionPopUp()
  2673. {
  2674.     Arg args[16];
  2675.     Widget dialog;
  2676.     Position x, y;
  2677.     Dimension bw_width, pw_width;
  2678.     int j;
  2679.  
  2680.     j = 0;
  2681.     XtSetArg(args[j], XtNwidth, &bw_width); j++;
  2682.     XtGetValues(boardWidget, args, j);
  2683.     
  2684.     j = 0;
  2685.     XtSetArg(args[j], XtNresizable, True); j++;
  2686.     promotionShell =
  2687.       XtCreatePopupShell("Promotion", transientShellWidgetClass,
  2688.              shellWidget, args, j);
  2689.     
  2690.     j = 0;
  2691.     XtSetArg(args[j], XtNlabel, "Promote pawn to what?"); j++;
  2692.     dialog = XtCreateManagedWidget("promotion", dialogWidgetClass,
  2693.                    promotionShell, args, j);
  2694.     
  2695.     XawDialogAddButton(dialog, "Queen", PromotionCallback, 
  2696.                (XtPointer) dialog);
  2697.     XawDialogAddButton(dialog, "Rook", PromotionCallback, 
  2698.                (XtPointer) dialog);
  2699.     XawDialogAddButton(dialog, "Bishop", PromotionCallback, 
  2700.                (XtPointer) dialog);
  2701.     XawDialogAddButton(dialog, "Knight", PromotionCallback, 
  2702.                (XtPointer) dialog);
  2703.     XawDialogAddButton(dialog, "cancel", PromotionCallback, 
  2704.                (XtPointer) dialog);
  2705.     
  2706.     XtRealizeWidget(promotionShell);
  2707.     
  2708.     j = 0;
  2709.     XtSetArg(args[j], XtNwidth, &pw_width); j++;
  2710.     XtGetValues(promotionShell, args, j);
  2711.     
  2712.     XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
  2713.               lineGap + squareSize/3 +
  2714.               ((toY == 7) ^ (flipView) ?
  2715.                0 : 6*(squareSize + lineGap)), &x, &y);
  2716.     
  2717.     j = 0;
  2718.     XtSetArg(args[j], XtNx, x); j++;
  2719.     XtSetArg(args[j], XtNy, y); j++;
  2720.     XtSetValues(promotionShell, args, j);
  2721.     
  2722.     XtPopup(promotionShell, XtGrabNone);
  2723.     
  2724.     promotionUp = True;
  2725. }
  2726.  
  2727. void PromotionCallback(w, client_data, call_data)
  2728.      Widget w;
  2729.      XtPointer client_data, call_data;
  2730. {
  2731.     String name;
  2732.     Arg args[16];
  2733.     int promoChar;
  2734.     
  2735.     XtSetArg(args[0], XtNlabel, &name);
  2736.     XtGetValues(w, args, 1);
  2737.     
  2738.     XtPopdown(w = XtParent(XtParent(w)));
  2739.     XtDestroyWidget(w);
  2740.     promotionUp = False;
  2741.     
  2742.     if (fromX == -1) return;
  2743.     
  2744.     if (strcmp(name, "cancel") == 0) {
  2745.     fromX = fromY = -1;
  2746.     return;
  2747.     } else if (strcmp(name, "Knight") == 0) {
  2748.     promoChar = 'n';
  2749.     } else {
  2750.     promoChar = ToLower(name[0]);
  2751.     }
  2752.  
  2753.     UserMoveEvent(fromX, fromY, toX, toY, promoChar);
  2754. }
  2755.  
  2756.  
  2757. void ErrorCallback(w, client_data, call_data)
  2758.      Widget w;
  2759.      XtPointer client_data, call_data;
  2760. {
  2761.     errorUp = False;
  2762.     XtPopdown(w = XtParent(XtParent(w)));
  2763.     XtDestroyWidget(w);
  2764.     if (errorExitStatus != -1) ExitEvent(errorExitStatus);
  2765. }
  2766.  
  2767.  
  2768. void ErrorPopDown()
  2769. {
  2770.     if (!errorUp) return;
  2771.     errorUp = False;
  2772.     XtPopdown(errorShell);
  2773.     XtDestroyWidget(errorShell);
  2774. }
  2775.  
  2776. void ErrorPopUp(title, label)
  2777.      char *title, *label;
  2778. {
  2779.     Arg args[16];
  2780.     Widget dialog;
  2781.     Position x, y;
  2782.     int xx, yy;
  2783.     Window junk;
  2784.     Dimension bw_width, pw_width;
  2785.     Dimension pw_height;
  2786.     int i;
  2787.     
  2788.     i = 0;
  2789.     XtSetArg(args[i], XtNresizable, True);  i++;
  2790.     errorShell = 
  2791.       XtCreatePopupShell(title, transientShellWidgetClass,
  2792.              shellWidget, args, i);
  2793.     
  2794.     i = 0;
  2795.     XtSetArg(args[i], XtNlabel, label);  i++;
  2796.     dialog = XtCreateManagedWidget("dialog", dialogWidgetClass,
  2797.                    errorShell, args, i);
  2798.     
  2799.     XawDialogAddButton(dialog, "ok", ErrorCallback, (XtPointer) dialog);
  2800.     
  2801.     XtRealizeWidget(errorShell);
  2802.     
  2803.     i = 0;
  2804.     XtSetArg(args[i], XtNwidth, &bw_width);  i++;
  2805.     XtGetValues(boardWidget, args, i);
  2806.     i = 0;
  2807.     XtSetArg(args[i], XtNwidth, &pw_width);  i++;
  2808.     XtSetArg(args[i], XtNheight, &pw_height);  i++;
  2809.     XtGetValues(errorShell, args, i);
  2810.  
  2811. #ifdef NOTDEF
  2812.     /* This code seems to tickle an X bug if it is executed too soon
  2813.        after xboard starts up.  The coordinates get transformed as if
  2814.        the main window was positioned at (0, 0).
  2815.     */
  2816.     XtTranslateCoords(boardWidget, (bw_width - pw_width) / 2,
  2817.               0 - pw_height - appData.borderYoffset
  2818.               + squareSize / 3, &x, &y);
  2819. #else
  2820.     XTranslateCoordinates(xDisplay, XtWindow(boardWidget),
  2821.               RootWindowOfScreen(XtScreen(boardWidget)),
  2822.               (bw_width - pw_width) / 2,
  2823.               0 - pw_height - appData.borderYoffset
  2824.               + squareSize / 3, &xx, &yy, &junk);
  2825.     x = xx;
  2826.     y = yy;
  2827. #endif
  2828.  
  2829.     i = 0;
  2830.     XtSetArg(args[i], XtNx, x);  i++;
  2831.     XtSetArg(args[i], XtNy, y);  i++;
  2832.     XtSetValues(errorShell, args, i);
  2833.  
  2834.     errorUp = True;
  2835.     XtPopup(errorShell, XtGrabNone);
  2836. }
  2837.  
  2838.  
  2839. char *ModeToWidgetName(mode)
  2840.      GameMode mode;
  2841. {
  2842.     switch (mode) {
  2843.       case BeginningOfGame:
  2844.     if (appData.icsActive)
  2845.       return "menuMode.ICS Client";
  2846.     else if (appData.noChessProgram ||
  2847.          *appData.cmailGameName != NULLCHAR)
  2848.       return "menuMode.Edit Game";
  2849.     else
  2850.       return "menuMode.Machine Black";
  2851.       case MachinePlaysBlack:
  2852.     return "menuMode.Machine Black";
  2853.       case MachinePlaysWhite:
  2854.     return "menuMode.Machine White";
  2855.       case TwoMachinesPlay:
  2856.     return "menuMode.Two Machines";
  2857.       case EditGame:
  2858.     return "menuMode.Edit Game";
  2859.       case PlayFromGameFile:
  2860.     return "menuFile.Load Game";
  2861.       case EditPosition:
  2862.     return "menuMode.Edit Position";
  2863.       case IcsPlayingWhite:
  2864.       case IcsPlayingBlack:
  2865.       case IcsObserving:
  2866.       case IcsIdle:
  2867.       case IcsExamining:
  2868.     return "menuMode.ICS Client";
  2869.       default:
  2870.       case EndOfGame:
  2871.     return NULL;
  2872.     }
  2873. }     
  2874.  
  2875. void ModeHighlight()
  2876. {
  2877.     Arg args[16];
  2878.     static int oldPausing = FALSE;
  2879.     static GameMode oldmode = (GameMode) -1;
  2880.     char *wname;
  2881.     
  2882.     if (pausing != oldPausing) {
  2883.     oldPausing = pausing;
  2884.     if (pausing) {
  2885.         XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
  2886.     } else {
  2887.         XtSetArg(args[0], XtNleftBitmap, None);
  2888.     }
  2889.     XtSetValues(XtNameToWidget(menuBarWidget, "menuMode.Pause"),
  2890.             args, 1);
  2891.  
  2892.     if (pausing) {
  2893.         XtSetArg(args[0], XtNbackground, buttonForegroundPixel);
  2894.         XtSetArg(args[1], XtNforeground, buttonBackgroundPixel);
  2895.     } else {
  2896.         XtSetArg(args[0], XtNbackground, buttonBackgroundPixel);
  2897.         XtSetArg(args[1], XtNforeground, buttonForegroundPixel);
  2898.     }
  2899.     XtSetValues(XtNameToWidget(buttonBarWidget, PAUSE_BUTTON), args, 2);
  2900.     }
  2901.  
  2902.     wname = ModeToWidgetName(oldmode);
  2903.     if (wname != NULL) {
  2904.     XtSetArg(args[0], XtNleftBitmap, None);
  2905.     XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);
  2906.     }
  2907.     wname = ModeToWidgetName(gameMode);
  2908.     if (wname != NULL) {
  2909.     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
  2910.     XtSetValues(XtNameToWidget(menuBarWidget, wname), args, 1);
  2911.     }
  2912.     oldmode = gameMode;
  2913. }
  2914.  
  2915.  
  2916. /*
  2917.  * Button/menu procedures
  2918.  */
  2919. void ResetProc(w, event, prms, nprms)
  2920.      Widget w;
  2921.      XEvent *event;
  2922.      String *prms;
  2923.      Cardinal *nprms;
  2924. {
  2925.     ResetGameEvent();
  2926. }
  2927.  
  2928. int LoadGamePopUp(f, gameNumber, title)
  2929.      FILE *f;
  2930.      int gameNumber;
  2931.      char *title;
  2932. {
  2933.     cmailMsgLoaded = FALSE;
  2934.     if (gameNumber == 0) {
  2935.     int error = GameListBuild(f);
  2936.     if (error) {
  2937.         DisplayError("Cannot build game list", error);
  2938.     } else if (!ListEmpty(&gameList) &&
  2939.            ((ListGame *) gameList.tailPred)->number > 1) {
  2940.         GameListPopUp(f, title);
  2941.         return TRUE;
  2942.     }
  2943.     GameListDestroy();
  2944.     gameNumber = 1;
  2945.     }
  2946.     return LoadGame(f, gameNumber, title, FALSE);
  2947. }
  2948.  
  2949. void LoadGameProc(w, event, prms, nprms)
  2950.      Widget w;
  2951.      XEvent *event;
  2952.      String *prms;
  2953.      Cardinal *nprms;
  2954. {
  2955.     FileNamePopUp("Load game file name?", "", LoadGamePopUp, "r");
  2956. }
  2957.  
  2958. void LoadNextGameProc(w, event, prms, nprms)
  2959.      Widget w;
  2960.      XEvent *event;
  2961.      String *prms;
  2962.      Cardinal *nprms;
  2963. {
  2964.     ReloadGame(1);
  2965. }
  2966.  
  2967. void LoadPrevGameProc(w, event, prms, nprms)
  2968.      Widget w;
  2969.      XEvent *event;
  2970.      String *prms;
  2971.      Cardinal *nprms;
  2972. {
  2973.     ReloadGame(-1);
  2974. }
  2975.  
  2976. void ReloadGameProc(w, event, prms, nprms)
  2977.      Widget w;
  2978.      XEvent *event;
  2979.      String *prms;
  2980.      Cardinal *nprms;
  2981. {
  2982.     ReloadGame(0);
  2983. }
  2984.  
  2985. void LoadPositionProc(w, event, prms, nprms)
  2986.      Widget w;
  2987.      XEvent *event;
  2988.      String *prms;
  2989.      Cardinal *nprms;
  2990. {
  2991.     FileNamePopUp("Load position file name?", "", LoadPosition, "r");
  2992. }
  2993.  
  2994. void SaveGameProc(w, event, prms, nprms)
  2995.      Widget w;
  2996.      XEvent *event;
  2997.      String *prms;
  2998.      Cardinal *nprms;
  2999. {
  3000.     FileNamePopUp("Save game file name?",
  3001.           DefaultFileName(appData.oldSaveStyle ? "game" : "pgn"),
  3002.           SaveGame, "a");
  3003. }
  3004.  
  3005. void SavePositionProc(w, event, prms, nprms)
  3006.      Widget w;
  3007.      XEvent *event;
  3008.      String *prms;
  3009.      Cardinal *nprms;
  3010. {
  3011.     FileNamePopUp("Save position file name?",
  3012.           DefaultFileName(appData.oldSaveStyle ? "pos" : "fen"),
  3013.           SavePosition, "a");
  3014. }
  3015.  
  3016. void ReloadCmailMsgProc(w, event, prms, nprms)
  3017.      Widget w;
  3018.      XEvent *event;
  3019.      String *prms;
  3020.      Cardinal *nprms;
  3021. {
  3022.     ReloadCmailMsgEvent(FALSE);
  3023. }
  3024.  
  3025. void MailMoveProc(w, event, prms, nprms)
  3026.      Widget w;
  3027.      XEvent *event;
  3028.      String *prms;
  3029.      Cardinal *nprms;
  3030. {
  3031.     MailMoveEvent();
  3032. }
  3033.  
  3034. void AutoSaveGame()
  3035. {
  3036.     SaveGameProc(NULL, NULL, NULL, NULL);
  3037. }
  3038.  
  3039.  
  3040. void QuitProc(w, event, prms, nprms)
  3041.      Widget w;
  3042.      XEvent *event;
  3043.      String *prms;
  3044.      Cardinal *nprms;
  3045. {
  3046.     ExitEvent(0);
  3047. }
  3048.  
  3049. void PauseProc(w, event, prms, nprms)
  3050.      Widget w;
  3051.      XEvent *event;
  3052.      String *prms;
  3053.      Cardinal *nprms;
  3054. {
  3055.     PauseEvent();
  3056. }
  3057.  
  3058.  
  3059. void MachineBlackProc(w, event, prms, nprms)
  3060.      Widget w;
  3061.      XEvent *event;
  3062.      String *prms;
  3063.      Cardinal *nprms;
  3064. {
  3065.     MachineBlackEvent();
  3066. }
  3067.  
  3068. void MachineWhiteProc(w, event, prms, nprms)
  3069.      Widget w;
  3070.      XEvent *event;
  3071.      String *prms;
  3072.      Cardinal *nprms;
  3073. {
  3074.     MachineWhiteEvent();
  3075. }
  3076.  
  3077.  
  3078. void TwoMachinesProc(w, event, prms, nprms)
  3079.      Widget w;
  3080.      XEvent *event;
  3081.      String *prms;
  3082.      Cardinal *nprms;
  3083. {
  3084.     TwoMachinesEvent();
  3085. }
  3086.  
  3087. void IcsClientProc(w, event, prms, nprms)
  3088.      Widget w;
  3089.      XEvent *event;
  3090.      String *prms;
  3091.      Cardinal *nprms;
  3092. {
  3093.     IcsClientEvent();
  3094. }
  3095.  
  3096. void EditGameProc(w, event, prms, nprms)
  3097.      Widget w;
  3098.      XEvent *event;
  3099.      String *prms;
  3100.      Cardinal *nprms;
  3101. {
  3102.     EditGameEvent();
  3103. }
  3104.  
  3105. void EditPositionProc(w, event, prms, nprms)
  3106.      Widget w;
  3107.      XEvent *event;
  3108.      String *prms;
  3109.      Cardinal *nprms;
  3110. {
  3111.     EditPositionEvent();
  3112. }
  3113.  
  3114. void EditCommentProc(w, event, prms, nprms)
  3115.      Widget w;
  3116.      XEvent *event;
  3117.      String *prms;
  3118.      Cardinal *nprms;
  3119. {
  3120.     if (editUp) {
  3121.     EditCommentPopDown();
  3122.     } else {
  3123.     EditCommentEvent();
  3124.     }
  3125. }
  3126.  
  3127. void AcceptProc(w, event, prms, nprms)
  3128.      Widget w;
  3129.      XEvent *event;
  3130.      String *prms;
  3131.      Cardinal *nprms;
  3132. {
  3133.     AcceptEvent();
  3134. }
  3135.  
  3136. void DeclineProc(w, event, prms, nprms)
  3137.      Widget w;
  3138.      XEvent *event;
  3139.      String *prms;
  3140.      Cardinal *nprms;
  3141. {
  3142.     DeclineEvent();
  3143. }
  3144.  
  3145. void CallFlagProc(w, event, prms, nprms)
  3146.      Widget w;
  3147.      XEvent *event;
  3148.      String *prms;
  3149.      Cardinal *nprms;
  3150. {
  3151.     CallFlagEvent();
  3152. }
  3153.  
  3154. void DrawProc(w, event, prms, nprms)
  3155.      Widget w;
  3156.      XEvent *event;
  3157.      String *prms;
  3158.      Cardinal *nprms;
  3159. {
  3160.     DrawEvent();
  3161. }
  3162.  
  3163. void AbortProc(w, event, prms, nprms)
  3164.      Widget w;
  3165.      XEvent *event;
  3166.      String *prms;
  3167.      Cardinal *nprms;
  3168. {
  3169.     AbortEvent();
  3170. }
  3171.  
  3172. void AdjournProc(w, event, prms, nprms)
  3173.      Widget w;
  3174.      XEvent *event;
  3175.      String *prms;
  3176.      Cardinal *nprms;
  3177. {
  3178.     AdjournEvent();
  3179. }
  3180.  
  3181. void ResignProc(w, event, prms, nprms)
  3182.      Widget w;
  3183.      XEvent *event;
  3184.      String *prms;
  3185.      Cardinal *nprms;
  3186. {
  3187.     ResignEvent();
  3188. }
  3189.  
  3190. void StopObservingProc(w, event, prms, nprms)
  3191.      Widget w;
  3192.      XEvent *event;
  3193.      String *prms;
  3194.      Cardinal *nprms;
  3195. {
  3196.     StopObservingEvent();
  3197. }
  3198.  
  3199. void StopExaminingProc(w, event, prms, nprms)
  3200.      Widget w;
  3201.      XEvent *event;
  3202.      String *prms;
  3203.      Cardinal *nprms;
  3204. {
  3205.     StopExaminingEvent();
  3206. }
  3207.  
  3208.  
  3209. void ForwardProc(w, event, prms, nprms)
  3210.      Widget w;
  3211.      XEvent *event;
  3212.      String *prms;
  3213.      Cardinal *nprms;
  3214. {
  3215.     ForwardEvent();
  3216. }
  3217.  
  3218.  
  3219. void BackwardProc(w, event, prms, nprms)
  3220.      Widget w;
  3221.      XEvent *event;
  3222.      String *prms;
  3223.      Cardinal *nprms;
  3224. {
  3225.     BackwardEvent();
  3226. }
  3227.  
  3228. void ToStartProc(w, event, prms, nprms)
  3229.      Widget w;
  3230.      XEvent *event;
  3231.      String *prms;
  3232.      Cardinal *nprms;
  3233. {
  3234.     ToStartEvent();
  3235. }
  3236.  
  3237. void ToEndProc(w, event, prms, nprms)
  3238.      Widget w;
  3239.      XEvent *event;
  3240.      String *prms;
  3241.      Cardinal *nprms;
  3242. {
  3243.     ToEndEvent();
  3244. }
  3245.  
  3246. void RevertProc(w, event, prms, nprms)
  3247.      Widget w;
  3248.      XEvent *event;
  3249.      String *prms;
  3250.      Cardinal *nprms;
  3251. {
  3252.     RevertEvent();
  3253. }
  3254.  
  3255. void TruncateGameProc(w, event, prms, nprms)
  3256.      Widget w;
  3257.      XEvent *event;
  3258.      String *prms;
  3259.      Cardinal *nprms;
  3260. {
  3261.     TruncateGameEvent();
  3262. }
  3263. void RetractMoveProc(w, event, prms, nprms)
  3264.      Widget w;
  3265.      XEvent *event;
  3266.      String *prms;
  3267.      Cardinal *nprms;
  3268. {
  3269.     RetractMoveEvent();
  3270. }
  3271.  
  3272. void MoveNowProc(w, event, prms, nprms)
  3273.      Widget w;
  3274.      XEvent *event;
  3275.      String *prms;
  3276.      Cardinal *nprms;
  3277. {
  3278.     MoveNowEvent();
  3279. }
  3280.  
  3281.  
  3282. void AlwaysQueenProc(w, event, prms, nprms)
  3283.      Widget w;
  3284.      XEvent *event;
  3285.      String *prms;
  3286.      Cardinal *nprms;
  3287. {
  3288.     Arg args[16];
  3289.  
  3290.     appData.alwaysPromoteToQueen = !appData.alwaysPromoteToQueen;
  3291.  
  3292.     if (appData.alwaysPromoteToQueen) {
  3293.     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
  3294.     } else {
  3295.     XtSetArg(args[0], XtNleftBitmap, None);
  3296.     }
  3297.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Always Queen"),
  3298.         args, 1);
  3299. }
  3300.  
  3301. void AutocommProc(w, event, prms, nprms)
  3302.      Widget w;
  3303.      XEvent *event;
  3304.      String *prms;
  3305.      Cardinal *nprms;
  3306. {
  3307.     Arg args[16];
  3308.  
  3309.     appData.autoComment = !appData.autoComment;
  3310.  
  3311.     if (appData.autoComment) {
  3312.     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
  3313.     } else {
  3314.     XtSetArg(args[0], XtNleftBitmap, None);
  3315.     }
  3316.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Comment"),
  3317.         args, 1);
  3318. }
  3319.  
  3320.  
  3321. void AutoflagProc(w, event, prms, nprms)
  3322.      Widget w;
  3323.      XEvent *event;
  3324.      String *prms;
  3325.      Cardinal *nprms;
  3326. {
  3327.     Arg args[16];
  3328.  
  3329.     appData.autoCallFlag = !appData.autoCallFlag;
  3330.  
  3331.     if (appData.autoCallFlag) {
  3332.     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
  3333.     } else {
  3334.     XtSetArg(args[0], XtNleftBitmap, None);
  3335.     }
  3336.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Flag"),
  3337.         args, 1);
  3338. }
  3339.  
  3340. void AutobsProc(w, event, prms, nprms)
  3341.      Widget w;
  3342.      XEvent *event;
  3343.      String *prms;
  3344.      Cardinal *nprms;
  3345. {
  3346.     Arg args[16];
  3347.  
  3348.     appData.autoObserve = !appData.autoObserve;
  3349.  
  3350.     if (appData.autoObserve) {
  3351.     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
  3352.     } else {
  3353.     XtSetArg(args[0], XtNleftBitmap, None);
  3354.     }
  3355.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Observe"),
  3356.         args, 1);
  3357. }
  3358.  
  3359. void AutosaveProc(w, event, prms, nprms)
  3360.      Widget w;
  3361.      XEvent *event;
  3362.      String *prms;
  3363.      Cardinal *nprms;
  3364. {
  3365.     Arg args[16];
  3366.  
  3367.     appData.autoSaveGames = !appData.autoSaveGames;
  3368.  
  3369.     if (appData.autoSaveGames) {
  3370.     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
  3371.     } else {
  3372.     XtSetArg(args[0], XtNleftBitmap, None);
  3373.     }
  3374.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Auto Save"),
  3375.         args, 1);
  3376. }
  3377.  
  3378. void BellProc(w, event, prms, nprms)
  3379.      Widget w;
  3380.      XEvent *event;
  3381.      String *prms;
  3382.      Cardinal *nprms;
  3383. {
  3384.     Arg args[16];
  3385.  
  3386.     appData.ringBellAfterMoves = !appData.ringBellAfterMoves;
  3387.  
  3388.     if (appData.ringBellAfterMoves) {
  3389.     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
  3390.     } else {
  3391.     XtSetArg(args[0], XtNleftBitmap, None);
  3392.     }
  3393.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Bell"),
  3394.         args, 1);
  3395. }
  3396.  
  3397.  
  3398. void FlipViewProc(w, event, prms, nprms)
  3399.      Widget w;
  3400.      XEvent *event;
  3401.      String *prms;
  3402.      Cardinal *nprms;
  3403. {
  3404.     flipView = !flipView;
  3405.     DrawPosition(True, NULL);
  3406. }
  3407.  
  3408. void OldSaveStyleProc(w, event, prms, nprms)
  3409.      Widget w;
  3410.      XEvent *event;
  3411.      String *prms;
  3412.      Cardinal *nprms;
  3413. {
  3414.     Arg args[16];
  3415.  
  3416.     appData.oldSaveStyle = !appData.oldSaveStyle;
  3417.  
  3418.     if (appData.oldSaveStyle) {
  3419.     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
  3420.     } else {
  3421.     XtSetArg(args[0], XtNleftBitmap, None);
  3422.     }
  3423.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Old Save Style"),
  3424.         args, 1);
  3425. }
  3426.  
  3427. void QuietPlayProc(w, event, prms, nprms)
  3428.      Widget w;
  3429.      XEvent *event;
  3430.      String *prms;
  3431.      Cardinal *nprms;
  3432. {
  3433.     Arg args[16];
  3434.  
  3435.     appData.quietPlay = !appData.quietPlay;
  3436.  
  3437.     if (appData.quietPlay) {
  3438.     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
  3439.     } else {
  3440.     XtSetArg(args[0], XtNleftBitmap, None);
  3441.     }
  3442.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Quiet Play"),
  3443.         args, 1);
  3444. }
  3445.  
  3446. void ShowCoordsProc(w, event, prms, nprms)
  3447.      Widget w;
  3448.      XEvent *event;
  3449.      String *prms;
  3450.      Cardinal *nprms;
  3451. {
  3452.     Arg args[16];
  3453.  
  3454.     appData.showCoords = !appData.showCoords;
  3455.  
  3456.     if (appData.showCoords) {
  3457.     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
  3458.     } else {
  3459.     XtSetArg(args[0], XtNleftBitmap, None);
  3460.     }
  3461.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Coords"),
  3462.         args, 1);
  3463.  
  3464.     DrawPosition(True, NULL);
  3465. }
  3466.  
  3467. void ShowThinkingProc(w, event, prms, nprms)
  3468.      Widget w;
  3469.      XEvent *event;
  3470.      String *prms;
  3471.      Cardinal *nprms;
  3472. {
  3473.     Arg args[16];
  3474.  
  3475.     ShowThinkingEvent(!appData.showThinking);
  3476.  
  3477.     if (appData.showThinking) {
  3478.     XtSetArg(args[0], XtNleftBitmap, xMarkPixmap);
  3479.     } else {
  3480.     XtSetArg(args[0], XtNleftBitmap, None);
  3481.     }
  3482.     XtSetValues(XtNameToWidget(menuBarWidget, "menuOptions.Show Thinking"),
  3483.         args, 1);
  3484. }
  3485.  
  3486.  
  3487. void AboutProc(w, event, prms, nprms)
  3488.      Widget w;
  3489.      XEvent *event;
  3490.      String *prms;
  3491.      Cardinal *nprms;
  3492. {
  3493.     char buf[MSG_SIZ];
  3494.  
  3495.     sprintf(buf, "%s version %s, patchlevel %s\n\n%s\n%s\n\n%s\n%s",
  3496.         PRODUCT, VERSION, PATCHLEVEL,
  3497.         "Copyright 1991 Digital Equipment Corporation",
  3498.         "Enhancements Copyright 1992-95 Free Software Foundation",
  3499.         "This program is free software and carries NO WARRANTY;",
  3500.         "see the file COPYING for more information.");
  3501.     ErrorPopUp("About XBoard", buf);
  3502. }
  3503.  
  3504. void HintProc(w, event, prms, nprms)
  3505.      Widget w;
  3506.      XEvent *event;
  3507.      String *prms;
  3508.      Cardinal *nprms;
  3509. {
  3510.     HintEvent();
  3511. }
  3512.  
  3513. void BookProc(w, event, prms, nprms)
  3514.      Widget w;
  3515.      XEvent *event;
  3516.      String *prms;
  3517.      Cardinal *nprms;
  3518. {
  3519.     BookEvent();
  3520. }
  3521.  
  3522. void AboutGameProc(w, event, prms, nprms)
  3523.      Widget w;
  3524.      XEvent *event;
  3525.      String *prms;
  3526.      Cardinal *nprms;
  3527. {
  3528.     AboutGameEvent();
  3529. }
  3530.  
  3531. void NothingProc(w, event, prms, nprms)
  3532.      Widget w;
  3533.      XEvent *event;
  3534.      String *prms;
  3535.      Cardinal *nprms;
  3536. {
  3537.     return;
  3538. }
  3539.  
  3540. void Iconify(w, event, prms, nprms)
  3541.      Widget w;
  3542.      XEvent *event;
  3543.      String *prms;
  3544.      Cardinal *nprms;
  3545. {
  3546.     Arg args[16];
  3547.     
  3548.     fromX = fromY = -1;
  3549.     
  3550.     XtSetArg(args[0], XtNiconic, False);
  3551.     XtSetValues(shellWidget, args, 1);
  3552.     XtSetArg(args[0], XtNiconic, True);
  3553.     XtSetValues(shellWidget, args, 1);
  3554. }
  3555.  
  3556. void DisplayMessage(message, extMessage)
  3557.      char *message, *extMessage;
  3558. {
  3559.     char buf[MSG_SIZ];
  3560.     Arg arg;
  3561.     
  3562.     if (extMessage) {
  3563.     if (*message) {
  3564.         sprintf(buf, "%s  %s", message, extMessage);
  3565.         message = buf;
  3566.     } else {
  3567.         message = extMessage;
  3568.     }
  3569.     }
  3570.     XtSetArg(arg, XtNlabel, message);
  3571.     XtSetValues(messageWidget, &arg, 1);
  3572. }
  3573.  
  3574. void DisplayTitle(text)
  3575.      char *text;
  3576. {
  3577.     Arg args[16];
  3578.     int i;
  3579.     char title[MSG_SIZ];
  3580.     char *icon;
  3581.  
  3582.     if (text == NULL) text = "";
  3583.  
  3584.     if (appData.titleInWindow) {
  3585.     i = 0;
  3586.     XtSetArg(args[i], XtNlabel, text);   i++;
  3587.     XtSetValues(titleWidget, args, i);
  3588.     }
  3589.  
  3590.     if (*text != NULLCHAR) {
  3591.     icon = text;
  3592.     sprintf(title, "%s: %s", programName, icon);
  3593.     } else if (appData.icsActive) {
  3594.     icon = appData.icsHost;
  3595.     sprintf(title, "%s: %s", programName, icon);
  3596.     } else if (appData.cmailGameName[0] != NULLCHAR) {
  3597.     icon = "CMail";
  3598.     sprintf(title, "%s: %s", programName, icon);
  3599.     } else if (appData.noChessProgram) {
  3600.     icon = programName;
  3601.     sprintf(title, "%s", programName);
  3602.     } else {
  3603.     if (StrStr(appData.firstChessProgram, "gnuchess")) {
  3604.         icon = "GNU Chess";
  3605.         sprintf(title, "%s: %s", programName, icon);
  3606.     } else {
  3607.         icon = strrchr(appData.firstChessProgram, '/');
  3608.         if (icon == NULL)
  3609.           icon = appData.firstChessProgram;
  3610.         else
  3611.           icon++;
  3612.         sprintf(title, "%s: %s", programName, icon);
  3613.     }
  3614.     }
  3615.     i = 0;
  3616.     XtSetArg(args[i], XtNiconName, (XtArgVal) icon);    i++;
  3617.     XtSetArg(args[i], XtNtitle, (XtArgVal) title);      i++;
  3618.     XtSetValues(shellWidget, args, i);
  3619. }
  3620.  
  3621.  
  3622. void DisplayError(message, error)
  3623.      String message;
  3624.      int error;
  3625. {
  3626.     extern char *sys_errlist[];
  3627.     char buf[MSG_SIZ];
  3628.  
  3629.     if (error == 0) {
  3630.     if (appData.debugMode || appData.matchMode) {
  3631.         fprintf(stderr, "%s: %s\n", programName, message);
  3632.     }
  3633.     ErrorPopUp("Error", message);
  3634.     } else {
  3635.     if (appData.debugMode || appData.matchMode) {
  3636.         fprintf(stderr, "%s: %s: %s\n",
  3637.             programName, message, sys_errlist[error]);
  3638.     }
  3639.     sprintf(buf, "%s: %s", message, sys_errlist[error]);
  3640.     ErrorPopUp("Error", buf);
  3641.     }    
  3642. }
  3643.  
  3644.  
  3645. void DisplayFatalError(message, error, status)
  3646.      String message;
  3647.      int error, status;
  3648. {
  3649.     extern char *sys_errlist[];
  3650.     char buf[MSG_SIZ];
  3651.  
  3652.     errorExitStatus = status;
  3653.     if (errorExitStatus != -1) {
  3654.     XtSetSensitive(menuBarWidget, False);
  3655.     XtSetSensitive(buttonBarWidget, False);
  3656.     XtUninstallTranslations(formWidget);
  3657.     XtUninstallTranslations(boardWidget);
  3658.     XtUninstallTranslations(whiteTimerWidget);
  3659.     XtUninstallTranslations(blackTimerWidget);
  3660.     }
  3661.     if (error == 0) {
  3662.     fprintf(stderr, "%s: %s\n", programName, message);
  3663.     ErrorPopUp("Fatal Error", message);
  3664.     } else {
  3665.     fprintf(stderr, "%s: %s: %s\n",
  3666.         programName, message, sys_errlist[error]);
  3667.     sprintf(buf, "%s: %s", message, sys_errlist[error]);
  3668.     ErrorPopUp("Fatal Error", buf);
  3669.     }
  3670. }
  3671.  
  3672.  
  3673. void DisplayInformation(message)
  3674.      String message;
  3675. {
  3676.     ErrorPopDown();
  3677.     ErrorPopUp("Information", message);
  3678. }
  3679.  
  3680. void RingBell()
  3681. {
  3682.     putc(BELLCHAR, stderr);
  3683. }
  3684.  
  3685. void EchoOn()
  3686. {
  3687.     system("stty echo\n");
  3688. }
  3689.  
  3690. void EchoOff()
  3691. {
  3692.     system("stty -echo\n");
  3693. }
  3694.  
  3695. char *UserName()
  3696. {
  3697.     return getpwuid(getuid())->pw_name;
  3698. }
  3699.  
  3700. char *HostName()
  3701. {
  3702.     static char host_name[MSG_SIZ];
  3703.     
  3704. #if HAVE_GETHOSTNAME
  3705.     gethostname(host_name, MSG_SIZ);
  3706.     return host_name;
  3707. #else /* not HAVE_GETHOSTNAME */
  3708. # if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H
  3709.     sysinfo(SI_HOSTNAME, host_name, MSG_SIZ);
  3710.     return host_name;
  3711. # else /* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
  3712.     return "localhost";
  3713. # endif /* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
  3714. #endif /* not HAVE_GETHOSTNAME */
  3715. }
  3716.  
  3717. XtIntervalId loadGameTimerXID = 0;
  3718.  
  3719. int LoadGameTimerRunning()
  3720. {
  3721.     return loadGameTimerXID != 0;
  3722. }
  3723.  
  3724. int StopLoadGameTimer()
  3725. {
  3726.     if (loadGameTimerXID != 0) {
  3727.     XtRemoveTimeOut(loadGameTimerXID);
  3728.     loadGameTimerXID = 0;
  3729.     return TRUE;
  3730.     } else {
  3731.     return FALSE;
  3732.     }
  3733. }
  3734.  
  3735. void LoadGameTimerCallback(arg, id)
  3736.      XtPointer arg;
  3737.      XtIntervalId *id;
  3738. {
  3739.     loadGameTimerXID = 0;
  3740.     LoadGameLoop();
  3741. }
  3742.  
  3743. void StartLoadGameTimer(millisec)
  3744.      long millisec;
  3745. {
  3746.     loadGameTimerXID =
  3747.       XtAppAddTimeOut(appContext, millisec,
  3748.               (XtTimerCallbackProc) LoadGameTimerCallback,
  3749.               (XtPointer) 0);
  3750. }
  3751.  
  3752. XtIntervalId clockTimerXID = 0;
  3753.  
  3754. int ClockTimerRunning()
  3755. {
  3756.     return clockTimerXID != 0;
  3757. }
  3758.  
  3759. int StopClockTimer()
  3760. {
  3761.     if (clockTimerXID != 0) {
  3762.     XtRemoveTimeOut(clockTimerXID);
  3763.     clockTimerXID = 0;
  3764.     return TRUE;
  3765.     } else {
  3766.     return FALSE;
  3767.     }
  3768. }
  3769.  
  3770. void ClockTimerCallback(arg, id)
  3771.      XtPointer arg;
  3772.      XtIntervalId *id;
  3773. {
  3774.     clockTimerXID = 0;
  3775.     DecrementClocks();
  3776. }
  3777.  
  3778. void StartClockTimer(millisec)
  3779.      long millisec;
  3780. {
  3781.     clockTimerXID =
  3782.       XtAppAddTimeOut(appContext, millisec,
  3783.               (XtTimerCallbackProc) ClockTimerCallback,
  3784.               (XtPointer) 0);
  3785. }
  3786.  
  3787. void DisplayTimerLabel(w, color, timer, highlight)
  3788.      Widget w;
  3789.      char *color;
  3790.      long timer;
  3791.      int highlight;
  3792. {
  3793.     char buf[MSG_SIZ];
  3794.     Arg args[16];
  3795.     
  3796.     if (appData.clockMode) {
  3797.     sprintf(buf, "%s: %s", color, TimeString(timer));
  3798.     XtSetArg(args[0], XtNlabel, buf);
  3799.     } else {
  3800.     sprintf(buf, "%s  ", color);
  3801.     XtSetArg(args[0], XtNlabel, buf);
  3802.     }
  3803.     
  3804.     if (highlight) {
  3805.     XtSetArg(args[1], XtNbackground, timerForegroundPixel);
  3806.     XtSetArg(args[2], XtNforeground, timerBackgroundPixel);
  3807.     } else {
  3808.     XtSetArg(args[1], XtNbackground, timerBackgroundPixel);
  3809.     XtSetArg(args[2], XtNforeground, timerForegroundPixel);
  3810.     }
  3811.     
  3812.     XtSetValues(w, args, 3);
  3813. }
  3814.  
  3815. void DisplayWhiteClock(timeRemaining, highlight)
  3816.      long timeRemaining;
  3817.      int highlight;
  3818. {
  3819.     Arg args[16];
  3820.     DisplayTimerLabel(whiteTimerWidget, "White", timeRemaining, highlight);
  3821.     if (highlight && iconPixmap == bIconPixmap) {
  3822.     iconPixmap = wIconPixmap;
  3823.     XtSetArg(args[0], XtNiconPixmap, iconPixmap);
  3824.     XtSetValues(shellWidget, args, 1);
  3825.     }
  3826. }
  3827.  
  3828. void DisplayBlackClock(timeRemaining, highlight)
  3829.      long timeRemaining;
  3830.      int highlight;
  3831. {
  3832.     Arg args[16];
  3833.     DisplayTimerLabel(blackTimerWidget, "Black", timeRemaining, highlight);
  3834.     if (highlight && iconPixmap == wIconPixmap) {
  3835.     iconPixmap = bIconPixmap;
  3836.     XtSetArg(args[0], XtNiconPixmap, iconPixmap);
  3837.     XtSetValues(shellWidget, args, 1);
  3838.     }
  3839. }
  3840.  
  3841. #define CPReal 1
  3842. #define CPComm 2
  3843. #define CPSock 3
  3844. #define CPLoop 4
  3845. typedef int CPKind;
  3846.  
  3847. typedef struct {
  3848.     CPKind kind;
  3849.     int pid;
  3850.     int fdTo, fdFrom;  
  3851. } ChildProc;
  3852.  
  3853.  
  3854. int StartChildProcess(cmdLine, pr)
  3855.      char *cmdLine; 
  3856.      ProcRef *pr;
  3857. {
  3858.     char *argv[64], *p;
  3859.     int i, pid;
  3860.     int to_prog[2], from_prog[2];
  3861.     ChildProc *cp;
  3862.     
  3863.     /* We do NOT feed the cmdLine to the shell; we just
  3864.        parse it into blank-separated arguments in the
  3865.        most simple-minded way possible.
  3866.     */
  3867.     i = 0;
  3868.     p = cmdLine;
  3869.     for (;;) {
  3870.     argv[i++] = p;
  3871.     p = strchr(p, ' ');
  3872.     if (p == NULL) break;
  3873.     *p++ = NULLCHAR;
  3874.     }
  3875.     argv[i] = NULL;
  3876.  
  3877.     SetUpChildIO(to_prog, from_prog);
  3878.  
  3879.     if ((pid = fork()) == 0) {
  3880.     /* Child process */
  3881.     dup2(to_prog[0], 0);
  3882.     dup2(from_prog[1], 1);
  3883.     close(to_prog[0]);
  3884.     close(to_prog[1]);
  3885.     close(from_prog[0]);
  3886.     close(from_prog[1]);
  3887.     dup2(1, fileno(stderr)); /* force stderr to the pipe */
  3888.  
  3889.         execvp(argv[0], argv);
  3890.     
  3891.     perror(argv[0]);
  3892.     exit(1);
  3893.     }
  3894.     
  3895.     /* Parent process */
  3896.     close(to_prog[0]);
  3897.     close(from_prog[1]);
  3898.     
  3899.     cp = (ChildProc *) calloc(1, sizeof(ChildProc));
  3900.     cp->kind = CPReal;
  3901.     cp->pid = pid;
  3902.     cp->fdFrom = from_prog[0];
  3903.     cp->fdTo = to_prog[1];
  3904.     *pr = (ProcRef) cp;
  3905.     return 0;
  3906. }
  3907.  
  3908. void DestroyChildProcess(pr)
  3909.      ProcRef pr;
  3910. {
  3911.     ChildProc *cp = (ChildProc *) pr;
  3912.  
  3913.     if (cp->kind != CPReal) return;
  3914.     if (kill(cp->pid, SIGTERM) == 0)
  3915.       wait((int *) 0);
  3916.     close(cp->fdFrom);
  3917.     close(cp->fdTo);
  3918. }
  3919.  
  3920. void InterruptChildProcess(pr)
  3921.      ProcRef pr;
  3922. {
  3923.     ChildProc *cp = (ChildProc *) pr;
  3924.  
  3925.     if (cp->kind != CPReal) return;
  3926.     (void) kill(cp->pid, SIGINT); /* stop it thinking */
  3927. }
  3928.  
  3929. int OpenTelnet(host, port, pr)
  3930.      char *host;
  3931.      char *port;
  3932.      ProcRef *pr;
  3933. {
  3934.     char cmdLine[MSG_SIZ];
  3935.  
  3936.     if (port[0] == NULLCHAR) {
  3937.     sprintf(cmdLine, "%s %s", appData.telnetProgram, host);
  3938.     } else {
  3939.     sprintf(cmdLine, "%s %s %s", appData.telnetProgram, host, port);
  3940.     }
  3941.     return StartChildProcess(cmdLine, pr);
  3942. }
  3943.  
  3944. int OpenTCP(host, port, pr)
  3945.      char *host;
  3946.      char *port;
  3947.      ProcRef *pr;
  3948. {
  3949. #if OMIT_SOCKETS
  3950.     DisplayFatalError("Socket support is not configured in", 0, 2);
  3951. #else /* !OMIT_SOCKETS */
  3952.     int s;
  3953.     struct sockaddr_in sa;
  3954.     struct hostent     *hp;
  3955.     unsigned short uport;
  3956.     ChildProc *cp;
  3957.  
  3958.     if ((s = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
  3959.     return errno;
  3960.     }
  3961.  
  3962.     memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
  3963.     sa.sin_family = AF_INET;
  3964.     sa.sin_addr.s_addr = INADDR_ANY;
  3965.     uport = (unsigned short) 0;
  3966.     sa.sin_port = htons(uport);
  3967.     if (bind(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in)) < 0) {
  3968.     return errno;
  3969.     }
  3970.  
  3971.     memset((char *) &sa, (int)0, sizeof(struct sockaddr_in));
  3972.     if (!(hp = gethostbyname(host))) {
  3973.     int b0, b1, b2, b3;
  3974.     if (sscanf(host, "%d.%d.%d.%d", &b0, &b1, &b2, &b3) == 4) {
  3975.         hp = (struct hostent *) calloc(1, sizeof(struct hostent));
  3976.         hp->h_addrtype = AF_INET;
  3977.         hp->h_length = 4;
  3978.         hp->h_addr_list = (char **) calloc(2, sizeof(char *));
  3979.         hp->h_addr_list[0] = (char *) malloc(4);
  3980.         hp->h_addr_list[0][0] = b0;
  3981.         hp->h_addr_list[0][1] = b1;
  3982.         hp->h_addr_list[0][2] = b2;
  3983.         hp->h_addr_list[0][3] = b3;
  3984.     } else {
  3985.         return ENOENT;
  3986.     }
  3987.     }
  3988.     sa.sin_family = hp->h_addrtype;
  3989.     uport = (unsigned short) atoi(port);
  3990.     sa.sin_port = htons(uport);
  3991.     memcpy((char *) &sa.sin_addr, hp->h_addr, hp->h_length);
  3992.  
  3993.     if (connect(s, (struct sockaddr *) &sa, 
  3994.         sizeof(struct sockaddr_in)) < 0) {
  3995.     return errno;
  3996.     }
  3997.  
  3998.     cp = (ChildProc *) calloc(1, sizeof(ChildProc));
  3999.     cp->kind = CPSock;
  4000.     cp->pid = 0;
  4001.     cp->fdFrom = s;
  4002.     cp->fdTo = s;
  4003.     *pr = (ProcRef) cp;
  4004.  
  4005. #endif /* !OMIT_SOCKETS */
  4006.  
  4007.     return 0;
  4008. }
  4009.  
  4010. int OpenCommPort(name, pr)
  4011.      char *name;
  4012.      ProcRef *pr;
  4013. {
  4014.     int fd;
  4015.     ChildProc *cp;
  4016.  
  4017.     fd = open(name, 2, 0);
  4018.     if (fd < 0) return errno;
  4019.  
  4020.     cp = (ChildProc *) calloc(1, sizeof(ChildProc));
  4021.     cp->kind = CPComm;
  4022.     cp->pid = 0;
  4023.     cp->fdFrom = fd;
  4024.     cp->fdTo = fd;
  4025.     *pr = (ProcRef) cp;
  4026.  
  4027.     return 0;
  4028. }
  4029.  
  4030. int OpenLoopback(pr)
  4031.      ProcRef *pr;
  4032. {
  4033.     ChildProc *cp;
  4034.     int to[2], from[2];
  4035.  
  4036.     SetUpChildIO(to, from);
  4037.  
  4038.     cp = (ChildProc *) calloc(1, sizeof(ChildProc));
  4039.     cp->kind = CPLoop;
  4040.     cp->pid = 0;
  4041.     cp->fdFrom = to[0];  /* note not from[0]; we are doing a loopback */
  4042.     cp->fdTo = to[1];
  4043.     *pr = (ProcRef) cp;
  4044.  
  4045.     return 0;
  4046. }
  4047.  
  4048. int OpenRcmd(host, user, cmd, pr)
  4049.      char *host, *user, *cmd;
  4050.      ProcRef *pr;
  4051. {
  4052.     DisplayFatalError("internal rcmd not implemented for Unix", 0, 1);
  4053.     return -1;
  4054. }    
  4055.  
  4056. #define INPUT_SOURCE_BUF_SIZE 4096
  4057.  
  4058. typedef struct {
  4059.     CPKind kind;
  4060.     int fd;
  4061.     FILE *f;
  4062.     int lineByLine;
  4063.     InputCallback func;
  4064.     XtInputId xid;
  4065.     char buf[INPUT_SOURCE_BUF_SIZE];
  4066. } InputSource;
  4067.  
  4068. void DoInputCallback(closure, source, xid) 
  4069.      caddr_t closure;
  4070.      int *source;
  4071.      XtInputId *xid;
  4072. {
  4073.     InputSource *is = (InputSource *) closure;
  4074.     int count;
  4075.     int error;
  4076.  
  4077.     if (is->lineByLine) {
  4078.     if (fgets(is->buf, INPUT_SOURCE_BUF_SIZE, is->f) == NULL) {
  4079.         error = ferror(is->f);
  4080.         if (error == 0)
  4081.           count = 0;
  4082.         else
  4083.           count = -1;
  4084.         (is->func)((InputSourceRef) is, is->buf, count, error);
  4085.     } else {
  4086.         (is->func)((InputSourceRef) is, is->buf, strlen(is->buf), 0);
  4087.     }
  4088.     } else {
  4089.     count = read(is->fd, is->buf, INPUT_SOURCE_BUF_SIZE);
  4090.     if (count == -1)
  4091.       error = errno;
  4092.     else
  4093.       error = 0;
  4094.     (is->func)((InputSourceRef) is, is->buf, count, error);
  4095.     }    
  4096. }
  4097.  
  4098. InputSourceRef AddInputSource(pr, lineByLine, func)
  4099.      ProcRef pr;
  4100.      int lineByLine;
  4101.      InputCallback func;
  4102. {
  4103.     InputSource *is;
  4104.     ChildProc *cp = (ChildProc *) pr;
  4105.  
  4106.     is = (InputSource *) calloc(1, sizeof(InputSource));
  4107.     is->lineByLine = lineByLine;
  4108.     is->func = func;
  4109.     if (pr == NoProc) {
  4110.     is->kind = CPReal;
  4111.     is->fd = fileno(stdin);
  4112.     } else {
  4113.     is->kind = cp->kind;
  4114.     is->fd = cp->fdFrom;
  4115.     }
  4116.     if (lineByLine) {
  4117.     is->f = fdopen(is->fd, "r");
  4118.     setbuf(is->f, NULL);
  4119.     }
  4120.     
  4121.     is->xid = XtAppAddInput(appContext, is->fd,
  4122.                 (XtPointer) (XtInputReadMask),
  4123.                 (XtInputCallbackProc) DoInputCallback,
  4124.                 (XtPointer) is);
  4125.     return (InputSourceRef) is;
  4126. }
  4127.  
  4128. void RemoveInputSource(isr)
  4129.      InputSourceRef isr;
  4130. {
  4131.     InputSource *is = (InputSource *) isr;
  4132.  
  4133.     if (is->xid == 0) return;
  4134.     XtRemoveInput(is->xid);
  4135.     if (is->lineByLine) {
  4136.     fclose(is->f);
  4137.     }
  4138.     is->xid = 0;
  4139. }
  4140.  
  4141. int OutputToProcess(pr, message, count, outError)
  4142.      ProcRef pr;
  4143.      char *message;
  4144.      int count;
  4145.      int *outError;
  4146. {
  4147.     ChildProc *cp = (ChildProc *) pr;
  4148.     int outCount;
  4149.  
  4150.     outCount = write(cp->fdTo, message, count);
  4151.     if (outCount == -1)
  4152.       *outError = errno;
  4153.     else
  4154.       *outError = 0;
  4155.     return outCount;
  4156. }
  4157.  
  4158.  
  4159.